React Fiber的创建怎样做,完整过程是什么
Admin 2022-10-28 群英技术资讯 661 次浏览
当前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进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
怎么利用配置文件来管理多个 Node.js 进程?本篇文章给大家介绍一下PM2用配置文件管理多个Node.js项目的方法,希望对大家有所帮助!
这篇文章主要为大家详细介绍了js代码实现多人聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
pkg是一个很不错的跨平台nodejs应用打包工具,使用此工具,我们只需要给与用户提供一个简单的可执行文件就可以了,同时代码也是二进制的,提高了代码的安全性备注:测试demo很简单,也比较典型,包装了sofa框架,我们可以直接查看graphqlapi以及openapi环境准备
本篇文章给大家带来了关于javascript的相关知识,主要介绍了JavaScript的起源与发展,JavaScript作为赋予网页生命的前端基础技术,它可以实现相应的效果和交互,是前端开发不可或缺的基本配置之一,下面一起来了解一下JavaScript的前世今生,希望对大家有帮助。
eval是全局对象的一个函数属性,用于计算某个字符串,并执行其中的JavaScript代码。函数语法是eval(string)。参数string表示要计算的字符串。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008