”Queueing a Series of State Updates”などを読む
これです
You will learn
- What “batching” is and how React uses it to process multiple state updates
- How to apply several updates to the same state variable in a row
setStateのバッチ処理って比較的最近追加された気がするけれどもいつだっけ。ドキュメント追加してくれたんですね。
React batches state updates
イベントハンドラ内でre-renderがバッチ処理されることを、ウェイターが注文を聞き取ることに例えている。
This might remind you of a waiter taking an order at the restaurant. A waiter doesn’t run to the kitchen at the mention of your first dish! Instead, they let you finish your order, let you make changes to it, and even take orders from other people at the table.
クリックのような複数の意図的なイベントはバッチ処理しない。
React does not batch across multiple intentional events like clicks—each click is handled separately. Rest assured that React only does batching when it’s generally safe to do. This ensures that, for example, if the first button click disables a form, the second click would not submit it again.
Updating the same state multiple times before the next render
これはworkしないけれど、
<button onClick={() => {
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}>+3</button>
これはworkする。
<button onClick={() => {
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
}}>+3</button>
n => n + 1
の部分をupdater functionと呼び、setState(updaterFunction)
の書き方で、Reactはupdater functionをキューに積んでいく。次のrenderのときにキューを解消していく。
このボタンを押すとnumberが42になることからわかるように、setStateの更新内容はとかくキューに積まれて行って、次のレンダリング時に順番に消化されていく。state variableは最後の結果を反映する。
<button onClick={() => {
setNumber(number + 5);
setNumber(n => n + 1);
setNumber(42);
}}>Increase the number</button>
Recap
上手な3行まとめ
- Setting state does not change the variable in the existing render, but it requests a new render.
- React processes state updates after event handlers have finished running. This is called batching.
- To update some state multiple times in one event, you can use setNumber(n => n + 1) updater function.
Challenge 2 of 2: Implement the state queue yourself
作ってみた系はいつも勉強になる。
export function getFinalState(baseState, queue) {
let finalState = baseState;
// TODO: do something with the queue...
queue.forEach((q)=>{
if(typeof q === 'function'){
finalState = q(finalState)
} else {
finalState = q
}
})
return finalState;
}
順番的には逆だけども、これも読んでおくか
You will learn
- What rendering means in React
- When and why React renders a component
- The steps involved in displaying a component on screen
- Why rendering does not always produce a DOM update
なんかめっちゃいい内容じゃない?
UI表示までの3stepsを、レストランで料理が運ばれてくるまでで例えながら説明している。
- Triggering a render (delivering the guest’s order to the kitchen)
- Rendering the component (preparing the order in the kitchen)
- Committing to the DOM (placing the order on the table)
Step 1: Trigger a render
renderには2種類ある。initial renderか、re-renderか。
initial renderはcreateRootが担当する。
re-renderはset state functionが引き起こす。
Step 2: React renders your components
“Rendering” is React calling your components.
initial renderではRoot Componentを呼び出し、re-renderではそれを引き起こしたset state functionを持つコンポーネントを呼び出す。
renderingは再帰的に行われる。
treeの全部をre-renderするのは多くの場合パフォーマンス上最適ではなく、Reactは計算をスキップするためのいくつかの手法がある。Performanceに関して、古いドキュメントがlinkされていた。
Step 3: React commits changes to the DOM
initial renderではappendChildを用いて全体を描画し、re-renderでは色々計算して最小限の再描画を行う。
React only changes the DOM nodes if there’s a difference between renders.
re-renderが全体で行われても、commitが全体で行われるわけではない。
render => commit => painting(browser rendering)
読んでみて
Render and Commitは「全ての基礎」という感じで、初心者の人におすすめしたい内容だった。それでいうとcreateRootのようなprimitiveなAPIのrefも読みたくなった。reactとreact-domが何故分かれているのか?どう分かれているのか?これらについて明確に答えられるようになりたい。