🌊
React useState内部実装を読んでみました(dispatchSetState)
サンプルコード
import { useState } from "react";
function App() {
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1)
}
const handleClick2 = () => {
setCount(c => c + 1)
}
return (
<div className='container'>
<button onClick={handleClick}>click</button>
<button onClick={handleClick2}>click2</button>
<p className='subContainer'>{count}</p>
</div>
);
}
export default App;
要するには、buttonをクリックしたら、setCountが走ります、stateの変化がview側に表現させるという例です。
では、Reactはどうやってこれを実現したのか見てみました。
結論
setCountを実行した後以下の処理が行いました。
- actionをキューに入れます
- Reactは全体を再レンダリングを促します
- キューにあるactionを消化します。
説明
1. actionをキューに入れま
ここのactionは
action + 1 というpremitive型
もしくは
c => c + 1 という関数型
どっちでもキューに入れられます、違うのは、3の消化する時に、関数というactionなら、実行されます。
queueの場所は以下です
function ComponentのFiberNode-> memorizedState -> queue -> pending
2.Reactは全体を再レンダリングを促します
Reactはactionをチェックします、メモしているstateとのアドレスが違う場合は、Schedulerで再レンダリングを走らせます
3. キューにあるactionを消化します。
関数をレンダリングする時に、useState関数を実行させ、キューにあるactionを全部とって、逐次に消化します。
消化した結果をもって、queue.lastRenderedStateを更新します。
そして、queue.pendingをnullにして、キューをクリアします。
説明動画
actionをキューにいれます。
actionを消化する
actionは関数の場合は
初期マウント後、dispatchとhookの存在ステータス
Discussion