10月1日、Reactチームが「React 19.2」を公開した。この記事では、Reactの最新リリースに含まれる新機能や改善点を紹介する。
新しいReactの機能
<Activity />
新コンポーネント<Activity>
はアプリを「アクティビティ」に分割して管理できる仕組みである。
これにより、画面上に表示する/隠すだけでなく、効果的にマウントやアンマウント、更新の優先度を制御できる。
// 従来
{isVisible && <Page />}
// 新しい書き方
<Activity mode={isVisible ? 'visible' : 'hidden'}>
<Page />
</Activity>
visible
: 子要素を表示し、副作用を実行するhidden
: 子要素を非表示にし、副作用をアンマウント、更新も遅延
バックグラウンドで非表示部分を先読みレンダリングし、次回のナビゲーションを高速化する用途などに有効である。
useEffectEvent
useEffect
内で外部システムからの「イベント」を処理する際、依存関係の扱いに苦労するケースが多かった。useEffectEvent
を用いることで「イベント処理部分」をEffect本体から分離し、不要な再実行を防ぐことができる。
function ChatRoom({ roomId, theme }) {
const onConnected = useEffectEvent(() => {
showNotification('Connected!', theme);
});
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.on('connected', () => onConnected());
connection.connect();
return () => connection.disconnect();
}, [roomId]); // Effect Eventは依存関係に含めない
}
これにより、theme
変更時に接続が再確立されるといった不自然な挙動を避けられる。
cacheSignal
cache()
の寿命が切れるタイミングを検知できる仕組みが追加された。
レンダリングの中断や失敗時に不要な処理を中断する用途に役立つ。
import { cache, cacheSignal } from 'react';
const dedupedFetch = cache(fetch);
async function Component() {
await dedupedFetch(url, { signal: cacheSignal() });
}
パフォーマンストラック
Chrome DevToolsのパフォーマンスプロファイルに、React固有のトラックが追加された。
- Schedulerトラック: ユーザー操作に対するブロッキング更新や
startTransition
内の更新など、優先度ごとの作業を可視化 - Componentsトラック: コンポーネントツリーのマウント、Effect実行、ブロック状態などを時系列で確認可能
これにより、Reactの処理内容をより詳細に把握できる。
新しいReact DOMの機能
部分的プリレンダリング(Partial Pre-rendering)
アプリの静的部分を事前にレンダリングし、CDN経由で配信した後に動的部分を「再開」できる仕組みが導入された。
const { prelude, postponed } = await prerender(<App />, {
signal: controller.signal,
});
// preludeをCDNへ送信
await savePostponedState(postponed);
その後、resume
でSSRを継続したり、resumeAndPrerender
でSSG向けHTMLを生成できる。
これにより、SSRとSSGの柔軟な組み合わせが可能になった。
その他の変更点
SSRにおけるSuspenseのバッチ処理
これまでは、サーバーからストリーミングでコンテンツを送る際に、Suspense境界が準備でき次第すぐに表示へ切り替わっていた。そのため、ページの一部だけが中途半端に表示され、クライアント側の描画挙動と差が出るケースがあった。
React 19.2では、サーバー側のSuspense境界の「解放(reveal)」を短時間まとめてバッチ処理するようになった。これにより複数のコンテンツが一度に表示され、よりまとまった形でページが見えるようになる。
この変更は、SSRにおけるSuspenseでの<ViewTransition>
(※)サポートに備えるものでもある。まとめて描画されることでアニメーションの遷移も自然になり、細切れに更新されることで発生していたぎこちない動きを防ぐことができる。
さらに、 Web Vitals
(※) への影響も考慮されており、ページ全体の表示速度がLCPの目標値(2.5秒)に近づいた場合には、バッチ処理を止めて即座に表示する仕組みも導入されている。
※<ViewTransition>
: Web標準として策定中のAPIで、ページやUIを切り替える際に「前の状態」と「次の状態」をブラウザが認識し、自然なアニメーション(フェードやスライドなど)で遷移させるための仕組み。これまでは開発者が手作業でDOMやCSSを操作してアニメーションを実装する必要があったが、を使うとブラウザが状態遷移を抽象化してくれる。
※Web Vitals: Googleが定義しているWebサイトのユーザー体験を数値化するための指標群。表示速度、操作応答性、ビジュアルの安定性といった観点から、検索順位やSEOにも影響する重要な指標とされている。
※LCP(Largest Contentful Paint): Web Vitalsの中の一つで、ページ読み込み時に「最大の視覚的要素(画像やテキストブロックなど)が表示されるまでの時間」を計測する指標。ユーザーが「ページが表示された」と感じるタイミングに直結するため、Googleは2.5秒以内を「良好」と定義している。
Node.jsでのWeb Streams対応
React 19.2からは、Node.jsでサーバーサイドレンダリングを行う際にWeb Streamsを利用できるようになった。これにより、より幅広い環境で標準的なStreams APIが使えるようになった。
ただし、Node.jsに限っては依然として「Node Streams」の利用が推奨されている。(renderToPipeableStream, resumeToPipeableStream, prerenderToNodeStream, resumeAndPrerenderToNodeStream)理由はシンプルで、Node Streamsの方が圧倒的に高速で、しかも標準で圧縮もサポートしているからである。Web Streamsを使うと、場合によってはせっかくのストリーミングの利点を活かしきれない可能性がある。
eslint-plugin-react-hooks v6
- Flat configをデフォルト化
- React Compilerに対応した新ルールを導入
- 旧設定を使う場合は
recommended-legacy
に切り替え可能
useId
のprefix更新
- これまでの
:r:
や«r»
から_r_
へ変更。 - View TransitionsやXML 1.0互換性のため、CSSセレクタに使える形式になった。
React 19.2は「Activity」や「Partial Pre-rendering」といった開発体験に直結する新機能を備え、SSRやパフォーマンス解析の改善も進んだリリースである。
詳細は公式のリリースノートを参照いただきたい。