React源码
# React源码
思考:怎么更新时最快的?
v15: stack reconciler, 从根节点,一层层遍历
v16.9: fiber reconciler, 高优先级打断低优先级
v17.0.2:
- lagecy模式 - Fiber结构
- concurrent模式: 可以实现高优先级打断低优先级,但是没有正式发布
双缓存 canvas
浏览器一秒60帧,每隔 16.66ms 更新一次
Q: react为什么不用观察者模式?
太灵活了,不方便观察,vue是提供一种范式
# React的数据数据结构
# v-dom / element
# fiber
本质上一个数据结构
<div>
<h2>hello world</h2>
<p>{text}</p>
{
[...data].map(item => <Children data={item} />)
}
</div>
function FiberNode() {
this.tag = tag; // 标明是什么类型的 fiber
this.key = key;
this.type = null; // dom 元素的类型,
// 链表的形式,进行构建的
this.return = null; // 指向父节点
this.child = null ; // 子
this.sibling = null ; // 指向兄弟
//
// pendingProps, memoizedProps, updateQueue memorizeState
//
this.effectTag = NoEffect; // 用来收集 Effect
this.nextEffect = null; // 指向下一个 effect
this.firstEffect = null; // 第一个 effect
this.lastEffect = null; // 最后一个effect
//
this.alternate = null; // 双缓存树,current 指向对应的 workInProgress
}
// 示意
h2Fiber.return === divFiber;
divFiber.child === h2Fiber;
h2Fiber.sibling === pFiber;
pFiber.return === divFiber;
# dom
# React渲染流程
提示
react
- 提供一些和虚拟DOM相关的API
- 提供一些用户使用的hooks,component
react-reconciler
- render阶段
- beginWork
- completeWork
- commit 阶段
- commitWork
- render阶段
react-dom
- 提供在CRUD的情况下,处理DOM的API
- legacyRenderSubtreeIntoContainer
- updateContainer
- scheduleUpdateOnFiber
- performSyncWorkOnRoot
- renderRootSync
- workLoopSync
- performUnitOfWork
- workLoopSync
- renderRootSync
- performSyncWorkOnRoot
- scheduleUpdateOnFiber
- updateContainer
function workLoopSync() {
// Already timed out, so perform work without checking if we need to yield.
// 循环执行
while (workInProgress !== null) {
performUnitOfWork(workInProgress);
}
}
function performUnitOfWork() {
next = beginWork(current, unitWork);
if(next === null) {
next = completeUnitOfWork(nuitWork)
}
}
# BW 和 CW
# beginWork: 创建你的 workInProgress Fiber
使用 v-dom 和 current 对比,创建 workInProgress
beginWork 是一个向下调和的过程,就是由 fiberRoot 按照 child 指针逐层向下调和,期间会执行函数组件,实例类组件,diff 子节点,打上不同的 effectTag
- 对于组件,执行部分生命周期,执行render, 得到最新的children
- 向下遍历调和 children
- 打上不同的副作用标签 effectTag
# completeWork: 根据 effectTag, 创建 effectList 与真实 DOM
# commitWork
# 备注
react为什么不用观察者模式?
React v17 与 v18 的区别?
react源码相关的面试题收集?
上次更新: 9/4/2023, 10:57:40 PM