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,第二行调用 dispatcher 的 useState 方法并返回。
先看看用于创建 dispatcher 的 resolveDispatcher 方法。
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 部分的代码。