useState 从开始到放弃(改变计划)

75 阅读2分钟

useState 从开始到放弃(改变计划)

放弃从 useState 开始的原因

export function useState<S>(
  initialState: (() => S) | S
): [S, Dispatch<BasicStateAction<S>>] {
  const dispatcher = resolveDispatcher();
  return dispatcher.useState(initialState);
}

上一篇从这里开始,了解了一下 React 所使用的类型系统。 本来今天想看一下 useState 具体的代码。

对于这个 export 的 useState 而言,就只有两行代码。第一行创建一个 dispatcher,第二行调用 dispatcheruseState 方法并返回。

先看看用于创建 dispatcherresolveDispatcher 方法。

function resolveDispatcher() {
  const dispatcher = ReactCurrentDispatcher.current;
  if (__DEV__) {
    if (dispatcher === null) {
      console.error(
        "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for" +
          " one of the following reasons:\n" +
          "1. You might have mismatching versions of React and the renderer (such as React DOM)\n" +
          "2. You might be breaking the Rules of Hooks\n" +
          "3. You might have more than one copy of React in the same app\n" +
          "See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem."
      );
    }
  }
  // Will result in a null access error if accessed outside render phase. We
  // intentionally don't throw our own error because this is in a hot path.
  // Also helps ensure this is inlined.
  return ((dispatcher: any): Dispatcher);
}

这里也就是我觉得不能直接从 useState 开始的原因。可以看到 dispatcher 是直接取的 ReactCurrentDispatcher.current,那这个 ReactCurrentDispatcher.current 是在哪里赋值的呢?我全局搜索了一下,是在 packages/react-reconciler/src/ReactFiberHooks.new.js 中赋值的。当我尝试逐层往上去找相关逻辑时,我麻了。代码量太大,这样也不好理解相关逻辑。逐渐我觉得现在的学习的思路是不对的。

所以我改变了计划。

新计划

从新建一个 create-reract-app 项目入手,给项目的入口打断点,一步步理解学习重点代码的逻辑。由于 CRA 引入的 React 依赖都是构建后的,代码会和源码不同,所以我计划要在源码中找到对应的位置,理解逻辑。

重点会放在 React Core 部分、ReactDOM renderer 部分和 Reconciler 部分的代码。