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);
}