React Fiber的创建怎样做,完整过程是什么
Admin 2022-10-28 群英技术资讯 1005 次浏览
这篇文章给大家分享的是React Fiber的创建怎样做,完整过程是什么。小编觉得挺实用的,因此分享给大家做个参考,文中的介绍得很详细,而要易于理解和学习,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。当前React版本基于V17.0.2版本,本篇主要介绍fiber结构的创建。
个人理解,如有不对,请指出。
首先需要配置好React的debugger开发环境,入口在这里:github
执行npm run i,安装依赖,npm start运行环境。
通过在项目入口处调用React.render,打上Debug,查看React调用栈。
const root = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
root
);
在React调用render之后,在传入基础的配置后,调用legacyRenderSubtreeIntoContainer。
export function render(
element: React$Element<any>,
container: Container,
callback: ?Function,
) {
// 删除一些环境代码
// ...
return legacyRenderSubtreeIntoContainer(
null,
element,
container,
false,
callback,
);
}
在React调用render之后,在传入基础的配置后,调用legacyRenderSubtreeIntoContainer。
export function render(
element: React$Element<any>,
container: Container,
callback: ?Function,
) {
// 删除一些环境代码
// ...
return legacyRenderSubtreeIntoContainer(
null,
element,
container,
false,
callback,
);
}
legacyRenderSubtreeIntoContainer一共做了两件事情,一个是生成了fiberRoot,一个是调用updateContainer。

进入legacyCreateRootFromDOMContainer函数,查看如何生成fiberRoot。 在函数内部,调用了createLegacyRoot,在这里区分了下,是否使用hydrate,如下:
return createLegacyRoot(
container,
shouldHydrate
? {
hydrate: true,
}
: undefined,
);
对于createLegacyRoot来说,是用来实例化ReactDOMLegacyRoot函数的,通过后续调用,终于进入到root的生成,调用createRootImpl函数,实例化root。
进入createFiberRoot函数,初始化FiberRootNode。
function FiberRootNode(containerInfo, tag, hydrate) {
this.tag = tag; // 类型
this.containerInfo = containerInfo; // container
this.pendingChildren = null;
this.current = null;
this.pingCache = null;
this.finishedWork = null;
this.timeoutHandle = noTimeout;
this.context = null;
this.pendingContext = null;
this.hydrate = hydrate;
this.callbackNode = null;
this.callbackPriority = NoLanePriority;
this.eventTimes = createLaneMap(NoLanes);
this.expirationTimes = createLaneMap(NoTimestamp);
this.pendingLanes = NoLanes;
this.suspendedLanes = NoLanes;
this.pingedLanes = NoLanes;
this.mutableReadLanes = NoLanes;
this.finishedLanes = NoLanes;
this.entangledLanes = NoLanes;
this.entanglements = createLaneMap(NoLanes);
// ....
}
这里的tag,有以下几种类型。
export type RootTag = 0 | 1;
上述的结构是fiberRootNode节点。
rootTag 等于0 时,代表legacy渲染模式,等于1时,代表Concurrent mode渲染,也就是说,传统我们使用React.render进行渲染,当调用React.createRoot时,进入Concurrent mode渲染模式,即并行渲染。
现在我们一起看看fiber的结构。
const uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); root.current = uninitializedFiber; uninitializedFiber.stateNode = root;
uninitializedFiber为创建的FiberNode的创建的实例。
const createFiber = function(
tag: WorkTag,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
): Fiber {
// $FlowFixMe: the shapes are exact here but Flow doesn"t like constructors
return new FiberNode(tag, pendingProps, key, mode);
};
通过基础的创建,生成FiberNode结构,如下
function FiberNode(
tag: WorkTag,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
) {
// Instance
this.tag = tag;//组件类型
this.key = key;//key属性
this.elementType = null;//元素类型,类函数,显示类,div显示div
this.type = null;//func或者class
this.stateNode = null;//dom节点
// Fiber
this.return = null;//指向父节点
this.child = null;//指向子节点
this.sibling = null;//兄弟节点
this.index = 0;//
this.ref = null;
this.pendingProps = pendingProps;//等待中的属性pendingProps
this.memoizedProps = null; //记忆属性,一般存放props
this.updateQueue = null;//更新队列
this.memoizedState = null;// 一般存放state
this.dependencies = null;
this.mode = mode;
// Effects相关
this.flags = NoFlags;
this.subtreeFlags = NoFlags;
this.deletions = null;
this.lanes = NoLanes;
this.childLanes = NoLanes;
this.alternate = null;//指向workInProgress
}

FiberNode基本显示如上,elementType和type的基础类型为function、class。
通过对比fiberRootNode结构,和下面的代码,生成最终的FiberNode 结构。
render() {
const { name, count } = this.state;
return (
<div className="App">
<Button name={name} />
{
count
}
</div>
);
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
root
);
通过最后执行,生成fiberRoot链表结构。

最后,调用unbatchedUpdates,进行渲染。
进入updateContainer函数。
unbatchedUpdates(() => {
// 更新container
updateContainer(children, fiberRoot, parentComponent, callback);
});
原文链接:https://juejin.cn/post/6950692243485229086
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了Vue3中的Refs和Ref,文章围绕Vue3中的Refs和Ref得相关资料应用举例烦人方式展开详细内容,需要的朋友可以参考一下
这篇文章给大家分享的是JavaScript ES模块使用的相关内容,介绍你可以在模块中导出和导入的所有方法,小编觉得挺实用的,因此分享给大家做个参考,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编看看吧。
目录前言什么是异常数据?接口异常拦截器中捕获异常前端异常为啥不用 window.onerror ?异常处理函数处理接口异常处理前端异常获取环境数据在 Vue 中在 React 中总结前言前两篇,我们介绍了为什么前端应该有监控系统,以及搭建前端监控的总体步骤,前端监控的 Why 和 What 想必你已经明白了。接下来我们
目录什么是备忘录?备忘录的概念1.引用透明2.查找表比较函数使用备忘录和不用备忘录解决方法是记录调用函数的返回结果备忘录的意义结论:什么是备忘录?前言;动态规划已出现了十多年。根据维基百科,它既是一种数学优化方法,也是一种计算机编程方法。一个问题要真正应用动态规划,必须具有两个关键属性:最优结构和重叠子结构。本文不会细
JS中浮点数转整数有哪些方法?JavaScript中,想要实现浮点数转整数,可以使用的方法有很多,例如使用parseInt()函数、利用位运算符“|”、利用位运算符“^”等等,具体怎样实现呢?下面我们看具体的示例,需要的朋友可以参考。
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 ICP核准(ICP备案)粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008