useState
useState 的工作流程可以分为两步:
- 声明阶段:在组件渲染时执行 useState 方法
- 调用阶段:触发点击事件时,执行 dispatch(通过 useState 返回的数组的第二个参数)
调用阶段
首先通过点击事件会执行 dispatch 方法。在 React 源码当中 dispatch 对应的是 dispatchAction 方法。
在 dispatchAction 方法内部会创建 update 对象,其中 update 对象具有 action 和 next 等属性。action 属性一般指执行 dispatch 方法时传入的一个参数,可能是一个值也可能是一个函数。next 属性用来指向其他 update 构成单向环状链表数据结构。最后将 update 插入到 hook.queue.pending 这条单向环状链表中。最后执行 scheduleUpdateOnFiber 方法调度状态更新。
通过 scheduleUpdateOnFiber 方法会依次执行 ensureRootIsScheduled、perfornCouncurrentWorkOnRoot、renderRootConcurrent、performUnitOfWork、beginWork 方法。
在 beginWork 方法中会根据 workInProgress.tag 判断,如果是 FunctionComponent 会调用 updateFunctionComponent 方法。然后执行 renderWithHooks 方法来执行函数组件。
在执行函数组件时就会执行 useState。
声明阶段
通过 dispatch 方法触发的状态更新流程中执行的 useState 对应的是 updateReducer 方法。
在 updateReducer 方法中会获取当前 useState 对应的 hook。hook 是在 mount 阶段通过 mountWorkInProgressHook 方法创建的。它包含memoizedState、queue、next 等属性。
memoizedState 用来保存 useState 传入的 initialState 和计算后的 state。queue 用来保存 dispatch 创建的 update 单向链表。next 用来执行下一个 hook。
拿到 hook 后会执行计算 update 的逻辑。关键就是判断 action 是否是一个函数,如果是函数则将上次的state作为参数传递进去然后执行该函数。否则直接返回 action 。将最后的结果再保存到hook.memoizedState 属性上并返回。
后续的执行流程就是根据 FunctionComponent 的执行结果创建 workInProgress fiber 节点。然后接着执行 complelteWork 方法比较变化的属性然后保存到 fiber.updateQueue 属性上。
在 commit 阶段的 muatation 阶段执行变化属性的赋值到对应的 dom 节点上。
然后切换 fiberRootNode.current 指针由 current fiber 树切换为 workInProgress fiber 树。
结束更新。
标签:流程,update,dispatch,hook,useState,执行,方法 From: https://www.cnblogs.com/rocenjs/p/18361903