React18では、自動バッチ機能が搭載されました。

React17までは、promiseやsetTimeout、イベント内の更新でバッチ処理がされていませんでした。

例えば、React17で以下のコードを実行し、一回ボタンをクリックすると、

import "./App.css";
import { useState } from "react";

function App() {
  const [count, setCount] = useState(0);
  const [message, setMessage] = useState("");

  const onClick = () => {
    setTimeout(()=>{
      setMessage("クリックしました");
      setCount(count + 1);
    },100)
  }
  
  console.log("rendered");

  return (
    <div>
      <p>{count}</p>
      <p>{message}</p>
      <button onClick={onClick} >ボタン</button>
    </div>
  );
}

export default App;

image2

image3

console.logが2回読み込まれているのがわかります。

ちなみにuseStateを増やすと、

function App() {
  const [count, setCount] = useState(0);
  const [message, setMessage] = useState("");
  const [message2, setMessage2] = useState("");

  const onClick = () => {
    setTimeout(()=>{
      setMessage("クリック");
      setMessage2("しました");
      setCount(count + 1);
    },100)
  }
  
  console.log("rendered");

  return (
    <div>
      <p>{count}</p>
      <p>{message}{message2}</p>
      <button onClick={onClick} >ボタン</button>
    </div>
  );
}

export default App;

image4

image5

1回のクリックで、console.logが3回読み込まれました。

同じコードを使い、React18で実行してみます。

image6

ボタンをクリックすると、

image7

console.logの読み込みは、1回のみでした。

これは、React18の自動バッチ機能が有効になっており、ステートの更新を1回のレンダリングにまとめてくれているからです。

ブログ一覧