本文將講解useState
鉤子的實現(xiàn)捏鱼。useState
是基于useReducer
實現(xiàn)的衍慎。其reducer函數(shù)為:
function basicStateReducer<S>(state: S, action: BasicStateAction<S>): S {
// $FlowFixMe: Flow doesn't like mixed types
return typeof action === 'function' ? action(state) : action;
}
Mount階段
useState
的這個階段和useReducer
所完成的事情是一樣甥角,只是其reducer為basicStateReducer
垦搬,而useReducer
是由參數(shù)傳入:
-
useState
首先調(diào)用mountWorkInProgressHook
創(chuàng)建一個Hook對象 - 然后呼寸,計算初始狀態(tài)值
initialState
,該值可以是由第二個參數(shù)(當不傳第三個參數(shù)時)傳入猴贰,也可由第三個參數(shù)(只能是函數(shù))和第二個參數(shù)計算所得对雪。 - 創(chuàng)建
queue
以及dispatch
函數(shù) - 返回初始值
initialState
以及dispatch
函數(shù)
function mountState<S>(
initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
const hook = mountWorkInProgressHook();
if (typeof initialState === 'function') {
// $FlowFixMe: Flow doesn't like mixed types
initialState = initialState();
}
hook.memoizedState = hook.baseState = initialState;
const queue = (hook.queue = {
pending: null,
dispatch: null,
lastRenderedReducer: basicStateReducer,
lastRenderedState: (initialState: any),
});
const dispatch: Dispatch<
BasicStateAction<S>,
> = (queue.dispatch = (dispatchAction.bind(
null,
currentlyRenderingFiber,
queue,
): any));
return [hook.memoizedState, dispatch];
}
Update階段
這個階段是直接調(diào)用的updateReducer
,其邏輯大體與updateReducer
相同米绕。
function updateState<S>(
initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
return updateReducer(basicStateReducer, (initialState: any));
}