React Hooks(如 useState,useEffect )的出现,彻底改变了 React 函数组件的编写方式。其看似神奇的实现原理,背后是闭包和链表(或数组)数据结构的精巧运用。
在 React 内部,每个函数组件实例都对应一个 Fiber 节点。这个 Fiber 节点内部维护着一个有序的数据结构(可以想象成一个链表或数组),专门用来存储该组件所有 Hooks 的状态。
当组件首次渲染时,每调用一个 Hook(如useState('initial')),React 就会创建一个对应的 Hook 对象,并将其按调用顺序存入这个内部链表中当组件因为状态变化而再次渲染时,函数组件的代码会重新执行。每当遇到一个 Hook 调用,React 就会从内部链表中,按照上一次渲染时完全相同的顺序,取出对应的 Hook 对象,从而读取到之前保存的状态。 setstate 函数之所以能更新状态,是因为它通过闭包捕获了指向特定 Hook 对象的引用,并触发一个更新调度。
正是这种强依赖于调用顺序的机制,决定了 Hooks 的核心使用规则:只能在组件的顶层调用,绝不能在条件语句循环或嵌套函数中使用。如果在不同渲染之间,Hooks 的调用顺序或数量发生变化,React 内部的指针就会错位,无法将当前的 Hook 调用与正确的历史状态关联起来,导致状态混乱和不可预测的 bug。
React 通过调用顺序识别 Hooks,打乱顺序会导致状态映射错误。 这一规则看似限制,实则是其实现原理的直接体现,