Closed3

The Plan for React 18 がでたのでメモ

takewelltakewell

互換性を壊す変更は入れない予定?に思う。大きな新機能は3つっぽい

https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html

01: Automatic batching

https://github.com/reactwg/react-18/discussions/21

React でいうところのバッチ処理とかレンダリング のバッチ処理、すなわち、様々な再描画を別々のタイミングでやるのではなく、まとめてやってしまうということのよう。
これで再描画コストが削減され、より軽快な GUI を実現できる

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    setCount(c => c + 1); // Does not re-render yet
    setFlag(f => !f); // Does not re-render yet
    // React will only re-render once at the end (that's batching!)
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}

この例だと 2種類の state の変更をまとめて実行でき、バッチレンダリングになる。
しかし、以下の例ではならないらしい。(一貫性がないことを問題視している模様)


function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    fetchSomething().then(() => {
      // React 17 and earlier does NOT batch these because
      // they run *after* the event in a callback, not *during* it
      setCount(c => c + 1); // Causes a re-render
      setFlag(f => !f); // Causes a re-render
    });
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}

例えば fetch の コールバックに state 変更を入れた場合はバッチレンダリングにならないらしい

というか、逆にイベントハンドラー onClick onChange 系以外のコールバックはバッチ処理にならないらしい。

これを ReactDOM.createRoot() という新しい API を使うと自動でバッチレンダリングしてくれるとのこと。

takewelltakewell

02 startTransition

https://github.com/reactwg/react-18/discussions/41

これは凄そう。
例えば検索バーとかによくあるインクリメンタルサーチとかに有効そう。

無茶苦茶ザクにいうと、state が変わってる(際描画中)はユーザーは画面に変更を加えることができずにその描画を待たないといけない。以下のように startTransition API で優先順位をつけることで ユーザーのインタラクション (例では setInputValue が 再実行された場合は setSetchQuery の 再描画は中断され破棄される。なので迅速にユーザーのインタラクションを反映することができる。多分...

import { startTransition } from 'react';

// Urgent: Show what was typed
setInputValue(input);

// Mark any state updates inside as transitions
startTransition(() => {
  // Transition: Show the results
  setSearchQuery(input);
});

takewelltakewell

03 New Suspense SSR Architecture

React 本体もついに SSR 機能に本腰を入れてきだした?Suspense と組み合わせて使うもののよう。
pipeToNodeWritable という API を追加して ストリーム描画的なの(順番に関心を持たない)をサポートするという感じに理解した。

https://github.com/reactwg/react-18/discussions/37

SSR って何をやってるかといえば以下のステップがある

1 : On the server, fetch data for the entire app.
2 : Then, on the server, render the entire app to HTML and send it in the response.
3 : Then, on the client, load the JavaScript code for the entire app.
4 : Then, on the client, connect the JavaScript logic to the server-generated HTML for the entire app (this is “hydration”)

単なる 2 だけを SSR という人がいるが React における SSR は 4 のクライアントの JSの描画結果を接続する Hydration レンダリングをするというのが肝。next とかはこれを使って 初期レンダリングはサーバーで実行、その結果をハイドレーションして、ブラウザーでライフサイクル処理を実行という形になっている。単に静的な HTML を返して Google によろこんでもらうために SSR しているのではない。最適化のため。

このステップの終了がそれぞれ終わらないとページ全体の描画が終わらないため、ほんの一部分が描画の全体に足を引っ張ってしまうという問題がある。

これを解決するのが <Suspense> を用いた。新しい SSR のよう。要は Suspense で囲った部分をユニット化して個別に SSR レンダリングできるようにする狙いがある。これで何か一箇所の処理が重くてレンダリングの全てが遅くなったりはしない。

(next あたりのフレームワークがこの機能を取り込んでくれてユーザー的には Suspense で囲っとけば OK みたいな状態になると予想。)

このスクラップは2022/03/29にクローズされました