4. 从 legacy 或 concurrent 开始 (从入口开始, 然后让我们奔向未来)
人人都能读懂的 react 源码解析(大厂高薪必备)
4.从 legacy 或 concurrent 开始(从入口开始,然后让我们奔向未来)
视频课程 &调试 demos
视频课程的目的是为了快速掌握 react 源码运行的过程和 react 中的 scheduler、reconciler、renderer、fiber 等,并且详细 debug 源码和分析,过程更清晰。
视频课程:进入课程
demos:demo
课程结构:
在前面的课程中我们已经学习了 react 的整体工作流程,对各个流程做的事情也有了大致的认识,现在让我们从 react 的入口开始学习各个部分的源码吧。
react 中入口函数的模式
首先,react 有 3 种模式进入主体函数的入口,我们可以从 react 官方文档 使用 Concurrent 模式(实验性)中对比三种模式
legacy 模式:
ReactDOM.render(<App />, rootNode)
。这是当前 React app 使用的方式。当前没有计划删除本模式,但是这个模式可能不支持这些新功能。blocking 模式:
ReactDOM.createBlockingRoot(rootNode).render(<App />)
。目前正在实验中。作为迁移到 concurrent 模式的第一个步骤。concurrent 模式:
ReactDOM.createRoot(rootNode).render(<App />)
。目前在实验中,未来稳定之后,打算作为 React 的默认开发模式。这个模式开启了所有的新功能。
特性对比:
*:legacy 模式在合成事件中有自动批处理的功能,但仅限于一个浏览器任务。非 React 事件想使用这个功能必须使用 unstable_batchedUpdates
。在 blocking 模式和 concurrent 模式下,所有的 setState
在默认情况下都是批处理的。
**:会在开发中发出警告。
不同模式在 react 运行时的含义
legacy 模式是我们常用的,它构建 dom 的过程是同步的,所以在 render 的 reconciler 中,如果 diff 的过程特别耗时,那么导致的结果就是 js 一直阻塞高优先级的任务(例如用户的点击事件),表现为页面的卡顿,无法响应。
concurrent Mode 是 react 未来的模式,它用时间片调度实现了异步可中断的任务,根据设备性能的不同,时间片的长度也不一样,在每个时间片中,如果任务到了过期时间,就会主动让出线程给高优先级的任务。这部分将在第 11 节 scheduler&lane 模型 这章会具体讲解 react 是如何实现异步可中断的任务,以及任务的优先级和高优先级是如果插队的。
函数调用的顺序和作用
主要流程:
主要函数执行过程:
看断点调试视频,函数调用细节更清楚:
用 demo_0 来看看执行过程:
legacy 模式主要函数注释:
concurrent 主要函数注释:
两种模式的不同点:
createRootImpl 中传入的第二个参数不一样 一个是 LegacyRoot 一个是 ConcurrentRoot
requestUpdateLane 中获取的 lane 的优先级不同
在函数 scheduleUpdateOnFiber 中根据不同优先级进入不同分支,legacy 模式进入 performSyncWorkOnRoot,concurrent 模式会异步调度 performConcurrentWorkOnRoot
版权声明: 本文为 InfoQ 作者【全栈潇晨】的原创文章。
原文链接:【http://xie.infoq.cn/article/1343d455faedc11895f64add9】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论