んだ日記

ndaDayoの技術日記です

useStateの内部実装読んでみるのメモ その2

前回の続きです。

nda-desu.hatenablog.com

前回は、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のライフサイクルを理解していこうと思う

僕から以上。あったかくして寝ろよー