Open IWSR opened 2 years ago
该文件内对 Hooks 内一些常见的函数/概念做解析
功能:同时移动 currentHook 与 workInProgressHook 这两个指针
let currentHook: Hook | null = null; let workInProgressHook: Hook | null = null; ... function updateWorkInProgressHook(): Hook { // 1. 移动 currentHook 指针 let nextCurrentHook: null | Hook; /** * currentHook / workInProgressHook 在初始化的时候都是null */ if (currentHook === null) { const current = currentlyRenderingFiber.alternate; // 获取当前 wip fiber 对应的 current fiber 节点 if (current !== null) { nextCurrentHook = current.memoizedState; // hooks 链表存储在 fiber 节点的 memoizedState 属性上 } else { nextCurrentHook = null; // current fiber 节点为空,那也不可能存在对应的 hooks 链表 } } else { nextCurrentHook = currentHook.next; // 指针后移 } let nextWorkInProgressHook: null | Hook; /** * 如果 WIP 的 hooks 为空,就把 WIP 上的 hooks 链表赋予它 * 否则 指针后移 */ if (workInProgressHook === null) { nextWorkInProgressHook = currentlyRenderingFiber.memoizedState; } else { nextWorkInProgressHook = workInProgressHook.next; } if (nextWorkInProgressHook !== null) { // There's already a work-in-progress. Reuse it. // 已经存在了 WIP 的 hooks 节点,复用即可 workInProgressHook = nextWorkInProgressHook; nextWorkInProgressHook = workInProgressHook.next; currentHook = nextCurrentHook; } else { // Clone from the current hook. // WIP hooks 的数量多于 current hooks 的数量,直接报错 // 因此不允许通过条件判断包裹 hooks,必须保证每次调用的 hooks 数量一致 if (nextCurrentHook === null) { throw new Error('Rendered more hooks than during the previous render.'); } /** * 借 currentHook 生成新的 workInProgressHook */ currentHook = nextCurrentHook; const newHook: Hook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, baseQueue: currentHook.baseQueue, queue: currentHook.queue, next: null, }; /** * 连接到 WIP Hook 的链表后面 */ if (workInProgressHook === null) { // This is the first hook in the list. currentlyRenderingFiber.memoizedState = workInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } } return workInProgressHook; }
附录
updateWorkInProgressHook
功能:同时移动 currentHook 与 workInProgressHook 这两个指针