react hook实现原理
React Hook 的实现原理
React Hook 的核心原理基于函数组件的闭包特性和Fiber架构的链表结构。Hook 通过维护一个全局的“当前 Hook”链表,确保在每次渲染时能正确追踪状态和副作用。
Hook 的底层数据结构
每个 Hook 在内部被表示为以下结构:
type Hook = {
memoizedState: any, // 存储当前状态(如useState的value)
baseState: any, // 基础状态用于更新计算
queue: UpdateQueue<any> | null, // 更新队列(用于useReducer/useState)
next: Hook | null, // 指向下一个Hook的指针
};
组件中的所有 Hook 会形成一个单向链表,React 通过currentHook和workInProgressHook指针追踪渲染过程。
useState/useReducer 的实现机制
状态 Hook 通过dispatcher在渲染时绑定到组件:
function useState(initialState) {
const dispatcher = resolveDispatcher();
return dispatcher.useState(initialState);
}
内部流程:

- 首次渲染时创建 Hook 对象,初始化
memoizedState - 调用
setState时会创建更新对象并加入queue - 重新渲染时按顺序遍历链表,应用更新队列计算新状态
状态更新公式: [ newState = baseState + \sum(update.action) ]
useEffect 的依赖追踪
useEffect通过比较依赖数组实现优化:
function useEffect(effect, deps) {
const hook = mountWorkInProgressHook();
if (areHookInputsEqual(nextDeps, prevDeps)) {
return;
}
hook.memoizedState = pushEffect(tag, effect);
}
关键点:

- 依赖数组使用
Object.is进行浅比较 - 副作用被标记为
PassiveEffect,在提交阶段统一执行 - 清理函数会在下次effect执行前被调用
Hook 调用规则的本质
强制要求每次渲染的 Hook 调用顺序一致的原因:
- Hook 链表依赖调用顺序来维护状态对应关系
- 条件语句可能导致链表断裂或错位
- 开发阶段通过
ESLint插件静态检查调用顺序
React 内部通过renderWithHooks函数在组件渲染时重置 Hook 索引:
let currentlyRenderingFiber = null;
let workInProgressHook = null;
自定义 Hook 的编译结果
自定义 Hook 会被编译为普通函数调用:
function useCustomHook() {
const [state] = useState();
return state;
}
// 编译后等同于多次调用原生Hook
Babel 转译不会对 Hook 做特殊处理,运行时依赖 React 的调度机制保证正确性。






