原理 - 调和(Reconciler)、fiber - 图1

知识点

Q:Element 与 fiber 之间的对应关系

  1. export const FunctionComponent = 0; // 对应函数组件
  2. export const ClassComponent = 1; // 对应的类组件
  3. export const IndeterminateComponent = 2; // 初始化的时候不知道是函数组件还是类组件
  4. export const HostRoot = 3; // Root Fiber 可以理解为跟元素 , 通过reactDom.render()产生的根元素
  5. export const HostPortal = 4; // 对应 ReactDOM.createPortal 产生的 Portal
  6. export const HostComponent = 5; // dom 元素 比如 <div>
  7. export const HostText = 6; // 文本节点
  8. export const Fragment = 7; // 对应 <React.Fragment>
  9. export const Mode = 8; // 对应 <React.StrictMode>
  10. export const ContextConsumer = 9; // 对应 <Context.Consumer>
  11. export const ContextProvider = 10; // 对应 <Context.Provider>
  12. export const ForwardRef = 11; // 对应 React.ForwardRef
  13. export const Profiler = 12; // 对应 <Profiler/ >
  14. export const SuspenseComponent = 13; // 对应 <Suspense>
  15. export const MemoComponent = 14; // 对应 React.memo 返回的组件

Q:fiber 作为 Element 与 真实 DOM 元素之间的沟通枢纽,fiber 上保存的信息,如下:

  1. function FiberNode(){
  2. this.tag = tag; // fiber 标签 证明是什么类型fiber。
  3. this.key = key; // key调和子节点时候用到。
  4. this.type = null; // dom元素是对应的元素类型,比如div,组件指向组件对应的类或者函数。
  5. this.stateNode = null; // 指向对应的真实dom元素,类组件指向组件实例,可以被ref获取。
  6. this.return = null; // 指向父级fiber
  7. this.child = null; // 指向子级fiber
  8. this.sibling = null; // 指向兄弟fiber
  9. this.index = 0; // 索引
  10. this.ref = null; // ref指向,ref函数,或者ref对象。
  11. this.pendingProps = pendingProps;// 在一次更新中,代表element创建
  12. this.memoizedProps = null; // 记录上一次更新完毕后的props
  13. this.updateQueue = null; // 类组件存放setState更新队列,函数组件存放
  14. this.memoizedState = null; // 类组件保存state信息,函数组件保存hooks信息,dom元素为null
  15. this.dependencies = null; // context或是时间的依赖项
  16. this.mode = mode; //描述fiber树的模式,比如 ConcurrentMode 模式
  17. this.effectTag = NoEffect; // effect标签,用于收集effectList
  18. this.nextEffect = null; // 指向下一个effect
  19. this.firstEffect = null; // 第一个effect
  20. this.lastEffect = null; // 最后一个effect
  21. this.expirationTime = NoWork; // 通过不同过期时间,判断任务是否过期, 在v17版本用lane表示。
  22. this.alternate = null; //双缓存树,指向缓存的fiber。更新阶段,两颗树互相交替。
  23. }

问:**fiber**是什么?**Fiber**架构解决了什么问题?


Q:**Fiber root****root fiber**有什么区别?

  • fiberRoot:首次构建应用,创建一个fiberRoot,作为整个 React 应用的根基;
  • rootFiberReactDOM.render渲染出来的,或组件也可作为一个rootFiber

一个 React 应用可有多个ReactDOM.render创建来的rootFiber,但只能有一个fiberRoot(应用根节点)。


问:不同**fiber**之间是如何建立起关联的?
问:React 调和流程?
问:两大阶段**commit****render**都做了哪些事情?


Q:什么是双缓冲树?有什么作用?
canvas 绘制动画,若上一帧计算量大,导致清除上一帧画面到绘制当前帧画面之间有较长间隙,会出现白屏。解决方案:canvas 在内存中绘制当前动画,绘制完毕后,直接用当前帧替换上一帧动画,省去了两帧替换间的计算时间,不会出现从白屏到有画面的闪烁情况。
这种在内存中构建并直接替换的技术叫 双缓存。

React 中的两棵树:

  • workInProgress树(内存中构建的树):在内存中构建。
  • current树(渲染树):渲染视图。

用这两棵树实现 更新 逻辑。两棵树用alternate指针相互指向,下一次渲染时,直接复用缓存树作为下一次渲染树,上一次的渲染树作为缓存树,可防止只用一棵树更新状态的丢失,也可加快 DOM 节点的替换、更新。


问:Fiber 深度遍历流程?
问:Fiber 的调和能中断吗?如何中断?