React Hooks的实现原理

8 阅读1分钟

React是在Fiber节点中保存的Hooks的状态的,通过Hooks的调用顺序找到对应状态,并在状态更新时触发对应组件的重新渲染.

Fiber节点

在React中,每个组件对应一个Fiber节点.简化的Fiber节点结构可以理解为:

const fiber = {
  type: Counter,
  memoizedState: null,//用来保存该函数组件的 Hooks 链表。
  alternate: null,
  // ...
};

memoizedState是用来保存该函数组件的 Hooks 链表。 其中链表的每个hook节点的结构可以简单理解为:

const hook = {
  memoizedState: null, // 当前状态
  baseState: null,     // 基础状态
  baseQueue: null,     // 基础更新队列
  queue: null,         // 更新队列
  next: null,          // 下一个 Hook
};

React 主要依靠 Hooks 的调用顺序,而不是变量名来识别不同的 Hook。 React 按照顺序遍历 Hook 链表,从而找到对应状态。

这也解释了为什么 Hooks 不能放在条件语句中.

useState的底层实现原理

我们可以把useState分为两个阶段,首次渲染与更新

首次渲染

const [count, setCount] = useState(0);

React 会:

  1. 创建一个 Hook 节点。
  2. 将初始值 0 保存到 memoizedState。
  3. 创建状态更新队列。
  4. 返回当前状态和 dispatch 函数。这里的 dispatch 就是我们熟悉的 setCount。

更新

setCount(prev => prev + 1);

setCount(prev => prev + 1)
          │
          ▼
创建 Update 对象
          │
          ▼
加入 Hook 更新队列
          │
          ▼
调度 Fiber 更新
          │
          ▼
重新执行 Counter 函数
          │
          ▼
处理更新队列,计算新状态
          │
          ▼
生成新的 React 元素
          │
          ▼
Reconciliation(协调)
          │
          ▼
Commit(提交 DOM 更新)