Hooks

Hooks 源码

ReactHooks入口

所有ReactHooks入口文件

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

export function useReducer<S, I, A>(
  reducer: (S, A) => S,
  initialArg: I,
  init?: I => S,
): [S, Dispatch<A>] {
  const dispatcher = resolveDispatcher();
  return dispatcher.useReducer(reducer, initialArg, init);
}

export function useRef<T>(initialValue: T): {|current: T|} {
  const dispatcher = resolveDispatcher();
  return dispatcher.useRef(initialValue);
}

export function useEffect(
  create: () => (() => void) | void,
  deps: Array<mixed> | void | null,
): void {
  const dispatcher = resolveDispatcher();
  return dispatcher.useEffect(create, deps);
}

export function useLayoutEffect(
  create: () => (() => void) | void,
  deps: Array<mixed> | void | null,
): void {
  const dispatcher = resolveDispatcher();
  return dispatcher.useLayoutEffect(create, deps);
}

export function useCallback<T>(
  callback: T,
  deps: Array<mixed> | void | null,
): T {
  const dispatcher = resolveDispatcher();
  return dispatcher.useCallback(callback, deps);
}

export function useMemo<T>(
  create: () => T,
  deps: Array<mixed> | void | null,
): T {
  const dispatcher = resolveDispatcher();
  return dispatcher.useMemo(create, deps);
}

export function useImperativeHandle<T>(
  ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,
  create: () => T,
  deps: Array<mixed> | void | null,
): void {
  const dispatcher = resolveDispatcher();
  return dispatcher.useImperativeHandle(ref, create, deps);
}

resolveDispatcher() 返回的是 ReactCurrentDispatcher.current,所以如 useState 其实就是 ReactCurrentDispatcher.current.useState。

ReactCurrentDispatcher

全局变量

Hooks类型定义

Hook

React 的 Hooks 是一个单向链表

Update & UpdateQueue

HooksDispatcherOnMount & HooksDispatcherOnUpdate

还有两个 Dispatch 的类型定义需要关注一下,一个是首次加载时的 HooksDispatcherOnMount,另一个是更新时的 HooksDispatcherOnUpdate。

首次渲染

React Fiber 会从 packages/react-reconciler/src/ReactFiberBeginWork.js 中的 beginWork() 开始执行,对于 Function Component,其走以下逻辑加载或更新组件:

updateFunctionComponent

renderWithHooks

React Hooks 的渲染核心入口是 renderWithHooks。

renderWithHooks 包括三个部分,ReactCurrentDispatcher.current,后续是做 didScheduleRenderPhaseUpdate 以及一些初始化的工作。核心是第一部分,我们来看看:

如果当前 Fiber 为空,就认为是首次加载,ReactCurrentDispatcher.current.useState 将赋值成 HooksDispatcherOnMount,否则赋值 HooksDispatcherOnUpdate。

当setState

首次加载时,useState = ReactCurrentDispatcher.current.useState = HooksDispatcherOnMount.useState = mountState;

更新时 useState = ReactCurrentDispatcher.current.useState = HooksDispatcherOnUpdate.useState = updateState。

dispatchAction

更新

updateWorkInProgressHook

updateWorkInProgressHook 获取到了当前工作中的 workInProgressHook

reRender就是说在当前更新周期中又产生了新的更新,就继续执行这些更新知道当前渲染周期中没有更新为止

最后更新于

这有帮助吗?