React18では、「並行レンダリング(Concurrent Rendering)」という新しい仕組みが導入されたことで、アプリの動作がよりスムーズになるように進化しました。
React 18の主な新機能まとめ
| カテゴリ | 機能 | 説明 |
|---|---|---|
| レンダリング | 並行レンダリング(Concurrent Rendering) | ReactがUI更新の優先順位を自動で管理 |
| 状態更新 | 自動バッチ処理(Automatic Batching) | R複数の状態更新をまとめて効率的に処理 |
| 新しいフック | useTransition, useDeferredValue, useId |
並行レンダリングを活かすための新Hook |
| SSR関連 | createRoot, hydrateRoot |
サーバーサイドレンダリング(SSR)の仕組みを刷新 |
| Suspense改善 | 非同期コンポーネントの表示制御がより強力に | データ取得中のUIをスムーズに切り替え |
並行レンダリング(Concurrent Rendering)とは?
これがReact 18の一番重要な新機能です。
React 18からは、レンダリングを途中で一時停止・再開・キャンセルできる ,/b>ようになりました。
つまり:
■重い処理の途中でも、ユーザー操作(入力など)を優先して処理
■Reactが裏で新しいUIを準備し、タイミングよく切り替える
これが Concurrent Rendering(並行レンダリング) です。
関連する新Hook
1️⃣ useTransition
「重要じゃない更新(=後回しにできる更新)」を扱うHook。
import { useState, useTransition } from "react";
function SearchBox() {
const [input, setInput] = useState("");
const [results, setResults] = useState<string[]>([]);
const [isPending, startTransition] = useTransition();
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setInput(value);
// 重い処理は「後回し」にする
startTransition(() => {
const filtered = items.filter(item => item.includes(value));
setResults(filtered);
});
};
return (
<div>
<input value={input} onChange={handleChange} />
{isPending && <p>検索中...</p>}
<ul>{results.map(r => <li key={r}>{r}</li>)}</ul>
</div>
);
}
➡️ startTransition 内の処理は「低優先度」になるため、
ユーザーの入力が スムーズに反映されます。
2️⃣ useDeferredValue
「値の反映を少し遅らせたい」場合に使うHook。
const deferredSearchTerm = useDeferredValue(searchTerm);
➡️ 大量のリストなどを表示するときに、
入力とリスト更新のタイミングをずらしてカクつきを防ぎます。
3️⃣ useId
SSR(サーバーサイドレンダリング)でも安全なユニークIDを生成できる。
const id = useId();
<label htmlFor={id}>名前</label>
<input id={id} />
➡️ HTMLのidがクライアント・サーバーで一致するようになり、
フォームなどで重複しにくくなりました。
自動バッチ処理(Automatic Batching)
React 17までは、「同じイベント内で複数のsetState」があっても
状況によっては別々にレンダーされていました。
React 18からは、すべて自動で1回にまとめて処理(バッチ)されます。
// React 18ではこれらが1回の再レンダーで済む!
setCount(c => c + 1);
setText("更新!");
結果:無駄な再レンダーが減って、パフォーマンスがアップします。
createRootでの変更点
React 18では、新しいレンダリングエンジンを使うために
アプリの起動コードも少し変わりました。
// React 17 以前
ReactDOM.render(<App />, document.getElementById("root"));
// React 18 以降
import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById("root")!);
root.render(<App />);
これにより、並行レンダリングの機能が有効化されます。
| 機能 | 目的 | 効果 |
|---|---|---|
| 並行レンダリング | UI更新の優先順位を自動管理 | 操作が滑らかになる |
| useTransition / useDeferredValue | 重い更新を後回しに | 入力中のカクつきを防ぐ |
| 自動バッチ処理 | 状態更新をまとめて処理 | 無駄な再レンダーを減らす |
| useId | SSRでも安定したID生成 | フォームなどで便利 |
| createRoot | 新レンダリングエンジンの導入 | React 18の機能を有効化 |
サイト