知识点
Q:Element 与 fiber 之间的对应关系
export const FunctionComponent = 0; // 对应函数组件
export const ClassComponent = 1; // 对应的类组件
export const IndeterminateComponent = 2; // 初始化的时候不知道是函数组件还是类组件
export const HostRoot = 3; // Root Fiber 可以理解为跟元素 , 通过reactDom.render()产生的根元素
export const HostPortal = 4; // 对应 ReactDOM.createPortal 产生的 Portal
export const HostComponent = 5; // dom 元素 比如 <div>
export const HostText = 6; // 文本节点
export const Fragment = 7; // 对应 <React.Fragment>
export const Mode = 8; // 对应 <React.StrictMode>
export const ContextConsumer = 9; // 对应 <Context.Consumer>
export const ContextProvider = 10; // 对应 <Context.Provider>
export const ForwardRef = 11; // 对应 React.ForwardRef
export const Profiler = 12; // 对应 <Profiler/ >
export const SuspenseComponent = 13; // 对应 <Suspense>
export const MemoComponent = 14; // 对应 React.memo 返回的组件
Q:fiber 作为 Element 与 真实 DOM 元素之间的沟通枢纽,fiber 上保存的信息,如下:
function FiberNode(){
this.tag = tag; // fiber 标签 证明是什么类型fiber。
this.key = key; // key调和子节点时候用到。
this.type = null; // dom元素是对应的元素类型,比如div,组件指向组件对应的类或者函数。
this.stateNode = null; // 指向对应的真实dom元素,类组件指向组件实例,可以被ref获取。
this.return = null; // 指向父级fiber
this.child = null; // 指向子级fiber
this.sibling = null; // 指向兄弟fiber
this.index = 0; // 索引
this.ref = null; // ref指向,ref函数,或者ref对象。
this.pendingProps = pendingProps;// 在一次更新中,代表element创建
this.memoizedProps = null; // 记录上一次更新完毕后的props
this.updateQueue = null; // 类组件存放setState更新队列,函数组件存放
this.memoizedState = null; // 类组件保存state信息,函数组件保存hooks信息,dom元素为null
this.dependencies = null; // context或是时间的依赖项
this.mode = mode; //描述fiber树的模式,比如 ConcurrentMode 模式
this.effectTag = NoEffect; // effect标签,用于收集effectList
this.nextEffect = null; // 指向下一个effect
this.firstEffect = null; // 第一个effect
this.lastEffect = null; // 最后一个effect
this.expirationTime = NoWork; // 通过不同过期时间,判断任务是否过期, 在v17版本用lane表示。
this.alternate = null; //双缓存树,指向缓存的fiber。更新阶段,两颗树互相交替。
}
问:**fiber**
是什么?**Fiber**
架构解决了什么问题?
Q:**Fiber root**
和**root fiber**
有什么区别?
fiberRoot
:首次构建应用,创建一个fiberRoot
,作为整个 React 应用的根基;rootFiber
:ReactDOM.render
渲染出来的,或组件也可作为一个rootFiber
。
一个 React 应用可有多个ReactDOM.render
创建来的rootFiber
,但只能有一个fiberRoot
(应用根节点)。
问:不同**fiber**
之间是如何建立起关联的?
问:React 调和流程?
问:两大阶段**commit**
和**render**
都做了哪些事情?
Q:什么是双缓冲树?有什么作用?
canvas 绘制动画,若上一帧计算量大,导致清除上一帧画面到绘制当前帧画面之间有较长间隙,会出现白屏。解决方案:canvas 在内存中绘制当前动画,绘制完毕后,直接用当前帧替换上一帧动画,省去了两帧替换间的计算时间,不会出现从白屏到有画面的闪烁情况。
这种在内存中构建并直接替换的技术叫 双缓存。
React 中的两棵树:
workInProgress
树(内存中构建的树):在内存中构建。current
树(渲染树):渲染视图。
用这两棵树实现 更新 逻辑。两棵树用alternate
指针相互指向,下一次渲染时,直接复用缓存树作为下一次渲染树,上一次的渲染树作为缓存树,可防止只用一棵树更新状态的丢失,也可加快 DOM 节点的替换、更新。
问:Fiber 深度遍历流程?
问:Fiber 的调和能中断吗?如何中断?