Skip to content

Hook和Fiber的关系

Hook为什么不能在循环,条件或者嵌套函数中调用

  1. 保持Hooks的调用顺序一致:React依赖于Hooks的调用顺序来正确地关联内部状态。 如果你在循环、条件判断或嵌套函数中调用Hooks,这个顺序可能在不同的渲染中变化,导致React无法正确跟踪状态和副作用

  2. 确保组件的预测性和一致性:将Hooks置于条件判断或循环中,会使组件的行为变得不可预测和不一致。 例如,如果你在一个条件判断中使用了useState,并且这个条件在不同的渲染中变化,那么组件的状态将无法保持一致。

  3. 便于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架构

  1. 任务调度与状态一致性:在Fiber架构中,React可以暂停、中断、恢复和重启组件渲染的工作。这意味着组件的渲染过程不再是一个单一的连续过程。 为了保证状态的一致性和准确性,React需要一种可靠的机制来追踪和管理状态。Hooks正是这样一种机制。

  2. 调用顺序的重要性:由于Fiber可以随时中断和恢复组件的渲染,React需要确保在多次渲染之间能够准确地追踪每个Hook的状态。这就要求Hooks的调用顺序在每次渲染时都是一样的。如果Hooks的调用顺序因条件语句而改变,React将无法准确地追踪它们的状态,导致不可预测的行为。

  3. 并发模式的兼容性: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的双缓冲技术

单缓存的问题

在传统的单缓冲渲染过程中,图形直接在显示设备(如屏幕)的缓冲区上绘制。 这种方法的问题在于,渲染过程中的中间状态可能被直接展示给用户,导致闪烁或撕裂等不良视觉效果

双缓冲技术原理

  1. Fiber架构中,每个Fiber节点都有一个alternate属性,指向另一个Fiber节点,这个属性就是双缓冲技术的核心。
  2. 当前的Fiber树称为current Fiber树,通过alternate属性指向的另一个Fiber树称为workInProgress Fiber树
  3. 当前Fiber树和workInProgress Fiber树交替出现,从而实现了双缓冲技术。
  4. 当React开始渲染时,它会为每个Fiber节点创建一个workInProgress Fiber节点,这个节点是current Fiber节点的克隆。
  5. 当React开始渲染下一个节点时,它会为这个节点创建一个workInProgress Fiber节点,并将这个节点的alternate属性指向current Fiber节点。
  6. 当React完成对节点的渲染时,它会将这个节点的workInProgress Fiber节点复制到current Fiber节点,然后将current Fiber节点的alternate属性指向workInProgress Fiber节点。