Open aloerina01 opened 5 years ago
これだけ複雑だと「Hooksは魔法じゃない、ただの配列だ」とか言われても十分魔法に見えるんですが。
currentHook
とかworkInProgressHoo
とか定義されてる、これはHookインスタンスがComponentやFiberに依存しているわけではないってことなのかとりあえずuseReducerの中身のコアはこのへんっぽい
export function useReducer<S, A>(
reducer: (S, A) => S,
initialState: S,
initialAction: A | void | null,
): [S, Dispatch<A>] {
workInProgressHook = createWorkInProgressHook();
let queue: UpdateQueue<S, A> | null = (workInProgressHook.queue: any);
const dispatch: Dispatch<A> = (queue.dispatch: any);
const firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
let update = firstRenderPhaseUpdate;
do {
const action = update.action;
newState = reducer(newState, action);
update = update.next;
} while (update !== null);
return [newState, dispatch];
}
That's the purpose of React Fiber. Fiber is reimplementation of the stack, specialized for React components. You can think of a single fiber as a virtual stack frame.
fiberを1つの(仮想)コールスタックだと考える、これはとてもしっくりきた。fiberが何なのかをイメージできないままにソースを読むと、どんな実装がなされているか予測できなくて苦戦したから。
https://github.com/tranbathanhtung/react-fiber-implement
ここにFiberのキーワードと概要がメモされてて、いろいろ読んだ後だと理解を後押ししてくれる。初見だと何言ってるか分からなかったと思う
読み直し。 いろいろ読み解けてきた。
nextUnitOfWork
にこれから実行するスタック(Fiber)が常にはいってくる感じ
react/ReactUpdateQueue.js at master · facebook/react
おそらく、段階的に画面が更新されてちらつくのを防ぐために、現在の状態とWorkInProgressの状態を比較して差分を出して、全てオフスクリーンで描画してから画面に一気に描画する、、、という感じのことをしている?それがダブルバッファリングということ?
updateオブジェクトが
next
を持っている。この連結で順序を管理しているのでLinkedListということかな。Updateオブジェクトを持つキュー。
firstUpdate
とは、未消化の最初のUpdateオブジェクトを指すポインタ。lastUpdate
はその名の通りキューの最後のUpdateオブジェクト。キューの末尾に追加する処理(
appendUpdateToQueue
)を見ると分かりやすい。