react hook的实现原理
React Hook 的实现原理
React Hook 的核心原理是通过闭包和链表结构管理组件的状态和生命周期。Hook 只能在函数组件顶层调用,确保每次渲染时 Hook 的执行顺序一致,从而正确关联状态。
Hook 的闭包机制
每个 Hook 通过闭包保存当前组件的状态。例如,useState 返回的状态和更新函数通过闭包访问当前组件的 Fiber 节点(React 内部用于描述组件的数据结构)。闭包确保状态在多次渲染中保持独立。
function useState(initialState) {
const fiber = currentlyRenderingFiber;
const hook = createHook(); // 创建或复用 Hook 对象
hook.memoizedState = initialState; // 存储初始状态
const setState = (newState) => {
hook.memoizedState = newState;
scheduleUpdate(); // 触发组件重新渲染
};
return [hook.memoizedState, setState];
}
Hook 的链表结构
React 使用链表结构管理多个 Hook。每次组件渲染时,Hook 按调用顺序被添加到链表中。例如,一个组件调用两次 useState,React 会维护如下链表:
{
memoizedState: 'state1', // 第一个 Hook 的状态
next: {
memoizedState: 'state2', // 第二个 Hook 的状态
next: null
}
}
Effect Hook 的实现
useEffect 通过调度机制在渲染后执行副作用。React 将副作用函数存储在 Hook 的 memoizedState 中,并在提交阶段(commit phase)统一处理:
function useEffect(effect, deps) {
const fiber = currentlyRenderingFiber;
const hook = createHook();
hook.memoizedState = { effect, deps }; // 存储副作用和依赖
scheduleEffect(effect); // 调度副作用执行
}
自定义 Hook 的本质
自定义 Hook 是普通函数组合内置 Hook 的逻辑。React 不会特殊处理自定义 Hook,其状态仍由调用它的组件通过链表管理。例如:
function useCustomHook() {
const [state, setState] = useState(0);
useEffect(() => { /* ... */ }, []);
return state;
}
Hook 的规则解析
- 顶层调用:保证 Hook 顺序一致,避免链表结构错乱。
- 仅在函数组件中使用:类组件已有实例管理状态,而函数组件依赖 Hook 的闭包和链表机制。
性能优化原理
useMemo 和 useCallback 通过依赖数组对比(Object.is)决定是否复用缓存值:
function useMemo(factory, deps) {
const hook = createHook();
if (areDepsEqual(hook.memoizedState?.deps, deps)) {
return hook.memoizedState.value; // 依赖未变化,返回缓存值
}
const newValue = factory();
hook.memoizedState = { value: newValue, deps };
return newValue;
}






