Hook和Fiber的关系
Hook为什么不能在循环,条件或者嵌套函数中调用
保持Hooks的调用顺序一致
:React依赖于Hooks的调用顺序来正确地关联内部状态
。 如果你在循环、条件判断或嵌套函数中调用Hooks,这个顺序可能在不同的渲染中变化,导致React无法正确跟踪状态和副作用
。确保组件的预测性和一致性
:将Hooks置于条件判断或循环中,会使组件的行为变得不可预测和不一致。 例如,如果你在一个条件判断中使用了useState,并且这个条件在不同的渲染中变化,那么组件的状态将无法保持一致。便于React的未来优化
:React未来可能会对Hooks的调用顺序进行优化,使得在不同的渲染中,React可以跳过一些Hooks的执行。
Fiber是什么
- Fiber是
React 16
中引入的一种内部机制,其主要目的是提高React应用的性能,特别是在渲染和更新组件时。- 在旧的React架构中,整个组件树的渲染和更新过程是同步进行的,这会导致性能问题和长时间阻塞用户界面
- fiber是一个对象,多个fiber对象组成一个链表,有一个固定的结构,每个fiber对象都有一个return指针,指向父fiber对象,有一个child指针,指向第一个子fiber对象,有一个sibling指针,指向下一个兄弟fiber对象。
- 每个Fiber对象代表了React树中的一个节点,它包含了当前节点的相关信息(例如:节点类型、节点的属性、节点的子节点)以及与其他节点相关的状态(例如:当前节点是否需要更新、当前节点对应的DOM节点是哪个)等。
- fiber对象中有一个stateNode属性,指向真实的DOM节点或者组件实例。
- Fiber架构的核心在于它提供了一种更细粒度的任务调度方式。
- Fiber引入了一种能够将渲染工作切分成多个小任务的机制,这些小任务可以根据优先级被中断和恢复,从而优化性能和响应性。
Hooks与Fiber架构
任务调度与状态一致性
:在Fiber架构中,React可以暂停、中断、恢复和重启组件渲染的工作。这意味着组件的渲染过程不再是一个单一的连续过程。 为了保证状态的一致性和准确性,React需要一种可靠的机制来追踪和管理状态。Hooks正是这样一种机制。调用顺序的重要性
:由于Fiber可以随时中断和恢复组件的渲染,React需要确保在多次渲染之间能够准确地追踪每个Hook的状态。这就要求Hooks的调用顺序在每次渲染时都是一样的。如果Hooks的调用顺序因条件语句而改变,React将无法准确地追踪它们的状态,导致不可预测的行为。并发模式的兼容性
:React的Fiber架构为未来的并发模式(Concurrent Mode)打下了基础。在并发模式下,React可以同时处理多个任务,这对状态管理提出了更高的要求。Hooks需要遵循一定的规则,以确保即使在并发环境下也能保持状态的一致性和正确性。
Fiber三个阶段
1.渲染(Render)
任务分割与调度
:在Fiber架构中,渲染工作被分解成多个小任务。这允许React暂停、恢复和优先级调度这些任务,特别是在处理大型更新或深层组件树时。这种分割带来了更好的性能和响应性。生成Fiber树
:在渲染阶段,React遍历组件树并为每个组件生成一个Fiber节点。每个Fiber节点代表一个工作单位,包含该组件的状态、属性等信息。可中断性
:由于Fiber允许React将渲染过程分解成小任务,渲染阶段可以被中断。这对于优化长时间运行的渲染任务(如大列表)和保持应用响应性非常重要。任务优先级
:在渲染阶段,React会根据任务的优先级来决定任务的执行顺序。这使得React可以根据任务的优先级来调整任务的执行顺序,从而优化性能和响应性。
2.协调(Reconciliation)
虚拟DOM比对
:在这一阶段,React比较新旧虚拟DOM树来确定哪些部分需要更新。Fiber架构使得这个过程更高效,允许React记住在树中的位置,快速恢复或中断这个过程。确定变化
:React决定哪些组件需要更新,哪些可以保持不变。它为实际变化的部分创建工作任务。优先级赋予
:根据不同类型的更新,React可以为它们分配不同的优先级。例如,用户交互和动画可能比数据获取更具有优先级。
3.提交(Commit)
实际DOM更新
:在提交阶段,React将在协调阶段确定的更改应用到DOM上。这是一个同步、不可中断的过程,确保了用户界面的一致性。生命周期方法调用
:React在这个阶段调用如componentDidMount和componentDidUpdate等生命周期方法。副作用处理
:提交阶段是处理诸如网络请求或DOM操作等副作用的地方。
Fiber中断执行原理
在Fiber架构中,渲染工作被分解成多个小的单元。React会为这些小的渲染任务分配
时间片
,执行一小部分任务后,它可以将控制权交还给浏览器,以便浏览器可以处理其他工作,如用户输入、动画等。
这种机制是通过浏览器的requestIdleCallbackAPI
实现的,允许React在浏览器空闲时执行任务,而在需要中断时暂停。
Fiber的双缓冲技术
单缓存的问题
在传统的单缓冲渲染过程中,图形直接在显示设备(如屏幕)的缓冲区上绘制。 这种方法的问题在于,渲染过程中的中间状态可能被直接展示给用户,导致闪烁或撕裂等不良视觉效果
。
双缓冲技术原理
- Fiber架构中,每个Fiber节点都有一个
alternate
属性,指向另一个Fiber节点,这个属性就是双缓冲技术的核心。 - 当前的Fiber树称为
current Fiber树
,通过alternate属性指向的另一个Fiber树称为workInProgress Fiber树
。 - 当前
Fiber树和workInProgress Fiber树交替出现
,从而实现了双缓冲技术。 - 当React开始渲染时,它会为每个Fiber节点创建一个workInProgress Fiber节点,这个节点是current Fiber节点的克隆。
- 当React开始渲染下一个节点时,它会为这个节点创建一个workInProgress Fiber节点,并将这个节点的alternate属性指向current Fiber节点。
- 当React完成对节点的渲染时,它会将这个节点的workInProgress Fiber节点复制到current Fiber节点,然后将current Fiber节点的alternate属性指向workInProgress Fiber节点。