Closed16

”Queueing a Series of State Updates”などを読む

hajimismhajimism

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.

hajimismhajimism

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のときにキューを解消していく。

hajimismhajimism

このボタンを押すとnumberが42になることからわかるように、setStateの更新内容はとかくキューに積まれて行って、次のレンダリング時に順番に消化されていく。state variableは最後の結果を反映する。

      <button onClick={() => {
        setNumber(number + 5);
        setNumber(n => n + 1);
        setNumber(42);
      }}>Increase the number</button>
hajimismhajimism

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.
hajimismhajimism

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;
}

hajimismhajimism

順番的には逆だけども、これも読んでおくか
https://react.dev/learn/render-and-commit

hajimismhajimism

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

なんかめっちゃいい内容じゃない?

hajimismhajimism

UI表示までの3stepsを、レストランで料理が運ばれてくるまでで例えながら説明している。

  1. Triggering a render (delivering the guest’s order to the kitchen)
  2. Rendering the component (preparing the order in the kitchen)
  3. Committing to the DOM (placing the order on the table)
hajimismhajimism

Step 2: React renders your components

“Rendering” is React calling your components.

initial renderではRoot Componentを呼び出し、re-renderではそれを引き起こしたset state functionを持つコンポーネントを呼び出す。

renderingは再帰的に行われる。

hajimismhajimism

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が全体で行われるわけではない。

hajimismhajimism

読んでみて

Render and Commitは「全ての基礎」という感じで、初心者の人におすすめしたい内容だった。それでいうとcreateRootのようなprimitiveなAPIのrefも読みたくなった。reactとreact-domが何故分かれているのか?どう分かれているのか?これらについて明確に答えられるようになりたい。

このスクラップは2023/07/16にクローズされました