前回の続きです。
前回は、mountStateImpl
の実装を追ったので、呼び出し元のmountState()に戻って続きを開始です。
mountState
前回は、const hook = mountStateImpl(initialState);
までやった。
mountStateImpl
は、hookを初期化して返していた。
function mountState<S>( initialState: (() => S) | S, ): [S, Dispatch<BasicStateAction<S>>] { const hook = mountStateImpl(initialState); const queue = hook.queue; const dispatch: Dispatch<BasicStateAction<S>> = (dispatchSetState.bind( null, currentlyRenderingFiber, queue, ): any); queue.dispatch = dispatch; return [hook.memoizedState, dispatch]; }
const queue = hook.queue;
ここで、queueにhook.queueを代入しているが、このqueueは、mountStateImplの中で初期化されたqueueですね。
で、このqueueをDispatchの中に入れ込んでいる。
dispatchSetState
で、ここは何をしているのか?まずは、dispatchSetState
を見に行く。
dispatchSetState
は、なかなかにロング。
function dispatchSetState<S, A>( fiber: Fiber, queue: UpdateQueue<S, A>, action: A, ): void {
const lane = requestUpdateLane(fiber);
とあるので、Lane、つまり優先度やスケジュールを更新してーの、次はここ
if (isRenderPhaseUpdate(fiber)) { enqueueRenderPhaseUpdate(queue, update);
isRenderPhaseUpdate
これは、関数の名前そのままにレンダリングフェーズ中の更新かどうかを見ている。レンダリングフェーズ中であれば、enqueueRenderPhaseUpdateが呼び出される。
ここで同じことが語られていた! stackoverflow.com
まとめ
Hooksはlist構造でキュー的な実装ということも理解できたし、Event Handlerから呼び出されるのと、Top level of the componentから呼び出される時の内部的な関数が違うこともわかった。
無限ループに陥るケースもわかったので、ここは収穫。
次はreactのライフサイクルを理解していこうと思う
僕から以上。あったかくして寝ろよー