一、为什么不能把 Hook 的写法放到 if 判断中去?
React 的 Hook 规则明确规定,不能在条件语句中调用 Hook。这是因为 React 依赖 Hook 调用的顺序来管理组件的状态和生命周期。当组件重新渲染时,React 通过逐行执行 Hook 调用来确定每个 Hook 的位置及其对应的状态。如果在条件语句中使用 Hook,可能会导致不同的渲染周期中 Hook 的调用顺序发生变化,从而引发状态不一致或难以预测的错误。
二、setState 的合并操作是如何做到的?
setState 是一个异步函数,当你多次调用 setState 时,React 会将这些状态更新进行合并,而不是立即重新渲染组件。具体来说,React 会将传递给 setState 的更新对象放入一个队列中。然后,在一次完整的事件循环之后,React 会处理这个队列并将所有状态更新合并为一个更新操作。这种机制可以减少不必要的重新渲染,提升性能。
三、Hook 链表和 queue.pending 的环状链表都应该如何理解?
• Hook 链表:React 内部为每个组件维护了一个 Hook 链表。每次调用 Hook 时,React 都会创建一个新的 Hook 节点并将其添加到链表中。这个链表在组件的整个生命周期中持续存在,记录了所有 Hook 调用的信息。
• queue.pending 的环状链表:在处理状态更新时,React 采用了环状链表来存储 setState 更新队列。这个队列中的每个节点都代表一次状态更新。环状链表的特点是最后一个节点会指向第一个节点,从而形成一个闭环。这种设计可以高效地处理状态更新,尤其是在处理多个更新操作时,能够简化状态的合并与应用。
四、setState 之后,为什么无法直接拿到最新值?
这是因为 setState 是一个异步操作。React 会在调用 setState 后,先将更新的状态放入队列,然后等待事件循环结束或批量处理时才会真正更新组件的状态和重新渲染。在下一次渲染之前,你获取到的状态仍然是旧的。因此,无法在 setState 调用之后立即获取最新的状态值。
要想在 setState 后获取最新的状态,可以使用 useEffect 或 useLayoutEffect Hook。这些 Hook 会在组件更新后执行,可以保证拿到更新后的状态。