Skip to content

useState源码实现

packages/react/src/ReactHooks.js

js
export function useState(reducer, initialArg) {
  const dispatcher = resolveDispatcher();
  return dispatcher.useState(reducer, initialArg);
}

packages/react/src/React.js

js
import { useReducer, useState } from './ReactHooks';
import ReactSharedInternals from './ReactSharedInternals';
export {
  useReducer,
  useState,
  ReactSharedInternals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
}

packages/react/index.js

js
export { 
    __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
    useState,
    useReducer
 }

packages/react-reconciler/src/ReactFiberHooks.js

js
const HooksDispatcherOnMount = {
  useReducer: mountReducer,  // 在mount期间,使用mountReducer处理useReducer
  useState: mountState
}

const HooksDispatcherOnUpdate = {
  useReducer: updateReducer,
  useState: updateState
}

function baseStateReducer(state, action) {
  return typeof action === 'function' ? action(state) : action;
}

function updateState() {
  return updateReducer(baseStateReducer);
}

function mountState(initialState) {
  const hook = mountWorkInProgressHook();
  hook.memoizedState = initialState;
  const queue = {
    pending: null,
    dispatch: null,
    lastRenderedReducer: baseStateReducer,
    lastRenderedState: initialState
  }
  hook.queue = queue;
  const dispatch = (queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber, queue));
  return [hook.memoizedState, dispatch];
}

function dispatchSetState(fiber, queue, action) {
  const update = {
    action,
    hasEagerState: false,
    eagerState: null,
    next: null
  }
  const { lastRenderedReducer, lastRenderedState } = queue;
  const eagerState = lastRenderedReducer(lastRenderedState, action);
  update.hasEagerState = true;
  update.eagerState = eagerState;
  if (Object.is(eagerState, lastRenderedState)) {
    return;
  }
  const root = enqueueConcurrentHookUpdate(fiber, queue, update);
  scheduleUpdateOnFiber(root);
}

基于 VitePress 构建