React 16 源码瞎几把解读 【三 点 二】 react中的fiberRoot
〇、先来看看常用的常量
NoWork = 0
noTimeout = undefined
HostRoot = 3
NoContext = 0b000;
AsyncMode = 0b001;
StrictMode = 0b010;
ProfileMode = 0b100;
NoEffect = /* */ 0b00000000000
enableProfilerTimer = __PROFILE__
__PROFILE__: true
isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined'
一、制造root._internalRoot 的 createFiberRoot 方法
export function createFiberRoot(
containerInfo: any, // id=app 的 dom
isAsync: boolean, // false
hydrate: boolean, // false
): FiberRoot {
const uninitializedFiber = createHostRootFiber(isAsync);
const root = {
current: uninitializedFiber, // 添加fiber 属性 一直用它
containerInfo: containerInfo, // dom app
pendingChildren: null, earliestPendingTime: NoWork,
latestPendingTime: NoWork,
earliestSuspendedTime: NoWork,
latestSuspendedTime: NoWork,
latestPingedTime: NoWork, didError: false, pendingCommitExpirationTime: NoWork,
finishedWork: null,
timeoutHandle: noTimeout,
context: null,
pendingContext: null,
hydrate, //false
nextExpirationTimeToWorkOn: NoWork,
expirationTime: NoWork,
firstBatch: null,
nextScheduledRoot: null,
};
uninitializedFiber.stateNode = root;
return root;
}
通过上面的代码得知,造出来的root._internalRoot 是一个包含若干属性的对象,其中最重要的是一个名叫 current的属性,这个current属性在上一集我们说到虚拟dom渲染过程的时候被当做第一参数 传入了 渲染核心函数 enqueueUpdate中。
这个current属性是个核心
二、 制造current属性的createHostRootFiber(isAsync)方法
export function createHostRootFiber(
isAsync: boolean // false
): Fiber {
// export type TypeOfMode = number;
// export const NoContext = 0b000;
// export const AsyncMode = 0b001;
// export const StrictMode = 0b010;
// export const ProfileMode = 0b100;
let mode = isAsync ? AsyncMode | StrictMode : NoContext; // 0b000
// __PROFILE__: true,
// export const enableProfilerTimer = __PROFILE__;
// export const isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
if (enableProfilerTimer && isDevToolsPresent) {
// Always collect profile timings when DevTools are present.
// This enables DevTools to start capturing timing at any point–
// Without some nodes in the tree having empty base times.
mode |= ProfileMode; // 0b100
}
// export const HostRoot = 3; // Root of a host tree. Could be nested inside another node.
return createFiber(HostRoot, null, null, mode);
}
这些代码无非是通过入参 isAsync 确定了mode的值,用来决定创造出的current是个具有根节点属性的东西
三、通用方法createFiber -> new FiberNode(...)
createFiber方法只是简单的返回了 new FiberNode(...),我们只需要看FiberNode是个啥
function FiberNode(
tag: TypeOfWork,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
) {
// Instance
this.tag = tag;
this.key = key;
this.type = null;
this.stateNode = null; // Fiber
this.return = null;
this.child = null;
this.sibling = null;
this.index = 0; this.ref = null; this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
this.memoizedState = null;
this.firstContextDependency = null; this.mode = mode; // Effects
// export const NoEffect = /* */ 0b00000000000;
this.effectTag = NoEffect;
this.nextEffect = null; this.firstEffect = null;
this.lastEffect = null; this.expirationTime = NoWork; //
this.childExpirationTime = NoWork; // this.alternate = null; if (enableProfilerTimer) {
this.actualDuration = 0;
this.actualStartTime = 0;
this.selfBaseDuration = 0;
this.treeBaseDuration = 0;
}
}
附加了一堆将来fiber架构需要用到的属性,具体这些属性是干啥用的,咱们以后再分析
不知道大家还记不记得这个root从我们调用reactDOM.render 传入那个container 往上附加了多少有用的东西,现在来回顾一下:
container 就是咱们传入的那个真实dom
container = {
_reactRootContainer :{ // legacyCreateRootFromDOMContainer
_internalRoot: { // DOMRenderer.createContainer
current:{} // new FiberNode
}
}
}
在dom上附加了这么一串有用的对象
React 16 源码瞎几把解读 【三 点 二】 react中的fiberRoot的更多相关文章
- React 16 源码瞎几把解读 【二】 react组件的解析过程
一.一个真正的react组件编译后长啥样? 我们瞎几把解读了react 虚拟dom对象是怎么生成的,生成了一个什么样的解构.一个react组件不光由若干个这些嵌套的虚拟dom对象组成,还包括各种生命周 ...
- React 16 源码瞎几把解读 【三 点 一】 把react组件对象弄到dom中去(矛头指向fiber,fiber不解读这个过程也不知道)
一.ReactDOM.render 都干啥了 我们在写react的时候,最后一步肯定是 ReactDOM.render( <div> <Home name="home&qu ...
- React 16 源码瞎几把解读 【一】 从jsx到一个react 虚拟dom对象
一.jsx变createElement 每一个用jsx语法书写的react组件最后都会变成 react.createElement(...)这一坨东西, // 转变前 export default ( ...
- React 16 源码瞎几把解读 【前戏】 为啥组件外面非得包个标签?
〇.看前准备 1.自行clone react最新代码 2.自行搭建一个能跑react的test项目 一.看表面:那些插件 如何解析JSX 有如下一段代码: // ---- hearder.jsx 组件 ...
- React Fiber源码分析 (介绍)
写了分析源码的文章后, 总觉得缺少了什么, 在这里补一个整体的总结,输出个人的理解~ 文章的系列标题为Fiber源码分析, 那么什么是Fiber,官方给出的解释是: React Fiber是对核心算法 ...
- 《React Native 精解与实战》书籍连载「React Native 源码学习方法及其他资源」
此系列文章将整合我的 React 视频教程与 React Native 书籍中的精华部分,给大家介绍 React Native 源码学习方法及其他资源. 最后的章节给大家介绍 React Native ...
- React的React.createContext()源码解析(四)
一.产生context原因 从父组件直接传值到孙子组件,而不必一层一层的通过props进行传值,相比较以前的那种传值更加的方便.简介. 二.context的两种实现方式 1.老版本(React16.x ...
- React的React.createElement源码解析(一)
一.什么是jsx jsx是语法糖 它是js和html的组合使用 二.为什么用jsx语法 高效定义模版,编译后使用 不会带来性能问题 三.jsx语法转化为js语法 jsx语法通过babel转化为 ...
- 【spring源码分析】IOC容器初始化(二)
前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...
随机推荐
- 精通android学习笔记(一)---广播
普通广播:sendBroadcast 有序广播:sendOrderedBroadcast,有序广播优先级可以再manifest中设置,数值越大,最先收到.-1000~1000 <receiver ...
- CRM 建设方案(01):CRM基础
CRM 客户关系管理系统基础 客户关系管理简称CRM(Customer Relationship Management).CRM概念引入中国已有数年,其字面意思是客户关系管理,但其深层的内涵却有着许多 ...
- 【数据库_Postgresql】实体类映射问题之不执行sql语句
后台controller到dao都没问题,前台页面接收的是一个实体类对象,在service层接收的也是对象,传入mapper里面的也是对象,没有用map,但是打印台却不执行sql语句,也没有明显错误提 ...
- 计算机网络:A、B、C、D和E类IP地址
IP地址分为A,B,C,D,E五类. 网络号:用于识别主机所在的网络:主机号:用于识别该网络中的主机. 其中A类分配给政府机关使用,B类地址给大中型企业使用,C类地址给个人使用.这三种是主要的. IP ...
- 【BZOJ2138】stone(线段树,Hall定理)
[BZOJ2138]stone(线段树,Hall定理) 题面 BZOJ 题解 考虑一个暴力. 我们对于每堆石子和每个询问,显然是匹配的操作. 所以可以把石子拆成\(a_i\)个,询问点拆成\(K_i\ ...
- PHP 中的新语法 new static 是个啥意思?
简单通俗的来说, self就是写在哪个类里面, 实际调用的就是这个类.所谓的后期静态绑定, static代表使用的这个类, 就是你在父类里写的static, 然后通过子类直接/间接用到了这个stati ...
- 【hdu4035】Maze
Portal --> hdu4035 Solution 讲道理不是很懂为啥概d那么喜欢走迷宫qwq (推式子推的很爽的一题?) 首先大力dp列式子 用\(f[i]\)表示从\(i\)到离开的期望 ...
- 机器学习算法的Python实现 (1):logistics回归 与 线性判别分析(LDA)
先收藏............ 本文为笔者在学习周志华老师的机器学习教材后,写的课后习题的的编程题.之前放在答案的博文中,现在重新进行整理,将需要实现代码的部分单独拿出来,慢慢积累.希望能写一个机器学 ...
- 【题解】Berland.Taxi Codeforces 883L 模拟 线段树 堆
Prelude 题目传送门:ヾ(•ω•`)o Solution 按照题意模拟即可. 维护一个优先队列,里面装的是正在运营中的出租车,关键字是乘客的下车时间. 维护一个线段树,第\(i\)个位置表示第\ ...
- 「Django」rest_framework学习系列-节流控制
1.节流自定义类: import time from api import models VISIT_RECORD = {} class VisitThrottle(BaseThrottle): #设 ...