React 19 の新機能まとめ(入門)
概要
React 19 は 2024 年 12 月に安定版がリリースされたメジャーバージョンです。フォーム処理まわりを大きく変える「Actions」、非同期処理をシンプルに扱う use API、forwardRef を不要にする ref の扱いの変更など、日々の実装に効く変更が多く入っています。
この記事では「まず何が変わったのか」を入門者向けに整理します。個別 API の細かい仕様は公式ドキュメントに譲り、全体像をつかむことを目的にします。
環境
- React 19(安定版)
- 記載のコードは概念を示すための最小例です
主な新機能
1. Actions(非同期処理と状態管理の統合)
React 19 では、非同期処理を useTransition の中で扱えるようになりました。従来は「保留中フラグ」「エラー」「楽観的更新」を自前の useState で管理しがちでしたが、Actions を使うとこの定型処理を減らせます。
import { useTransition } from "react";
function UpdateName() {
const [isPending, startTransition] = useTransition();
const onSubmit = () => {
startTransition(async () => {
const error = await updateName(name);
if (error) {
// エラー処理
return;
}
// 成功時の遷移など
});
};
return <button onClick={onSubmit} disabled={isPending}>更新</button>;
}
startTransition に渡す関数が非同期でも良くなった点がポイントです。処理中は isPending が自動で true になります。
2. useActionState
フォーム送信などの「アクションの結果」を状態として扱うためのフックです。送信関数・保留状態・直近の結果をまとめて管理できます。
import { useActionState } from "react";
function Form() {
const [state, formAction, isPending] = useActionState(
async (prevState, formData) => {
const error = await submit(formData);
return error ?? "ok";
},
null
);
return (
<form action={formAction}>
<input name="email" />
<button disabled={isPending}>送信</button>
{state && <p>{state}</p>}
</form>
);
}
<form action={...}> に関数を直接渡せるようになったのも 19 での変更点です。
3. useFormStatus
フォームの送信状態を、親からプロップスを渡さずに子コンポーネントから参照できるフックです。送信ボタンを共通部品化したいときに便利です。
import { useFormStatus } from "react-dom";
function SubmitButton() {
const { pending } = useFormStatus();
return <button disabled={pending}>送信</button>;
}
4. useOptimistic
サーバー応答を待つ間、UI を先に更新しておく「楽観的更新」を扱うフックです。応答が確定すると自動的に実際の値へ戻ります。
import { useOptimistic } from "react";
function Thread({ messages, sendMessage }) {
const [optimisticMessages, addOptimistic] = useOptimistic(
messages,
(state, newMessage) => [...state, { text: newMessage, sending: true }]
);
// フォーム送信時に addOptimistic を呼ぶ
}
5. use API
Promise やコンテキストを読み取る新しい API です。use は条件分岐やループの中でも呼べるため、これまでのフックのルールより柔軟に使えます。Promise を渡すと、解決するまでコンポーネントがサスペンドします。
import { use } from "react";
function Comments({ commentsPromise }) {
const comments = use(commentsPromise); // 解決までサスペンド
return comments.map((c) => <p key={c.id}>{c.text}</p>);
}
コンテキストの読み取りにも使えます。
const theme = use(ThemeContext);
6. ref をプロップスとして受け取れる
関数コンポーネントが ref を通常のプロップスとして受け取れるようになり、多くのケースで forwardRef が不要になりました。
function MyInput({ placeholder, ref }) {
return <input placeholder={placeholder} ref={ref} />;
}
// 使う側
<MyInput ref={inputRef} placeholder="名前" />
7. ref のクリーンアップ関数
ref コールバックからクリーンアップ関数を返せるようになりました。要素がアンマウントされる際に呼ばれます。
<input
ref={(node) => {
// セットアップ
return () => {
// クリーンアップ
};
}}
/>
8. ドキュメントメタデータのサポート
コンポーネント内に書いた <title> / <meta> / <link> が自動的に <head> へ引き上げられます。SEO まわりのタグ管理が素直に書けるようになりました。
function Article({ post }) {
return (
<article>
<title>{post.title}</title>
<meta name="description" content={post.summary} />
<h1>{post.title}</h1>
</article>
);
}
9. スタイルシート・スクリプト・リソースのプリロード
スタイルシートに読み込み優先度(precedence)を指定できるようになり、非同期スクリプトの重複読み込みも React 側で管理されます。あわせて preload / preinit / prefetchDNS / preconnect といったリソース先読み用の API が追加されました。
import { preload, preinit } from "react-dom";
preload("/fonts/main.woff2", { as: "font" });
preinit("/script.js", { as: "script" });
10. Context を直接プロバイダーとして使える
<Context.Provider> の代わりに <Context> をそのまま書けるようになりました。
const ThemeContext = createContext("");
function App({ children }) {
return <ThemeContext value="dark">{children}</ThemeContext>;
}
<Context.Provider> も引き続き使えますが、将来的には非推奨になる予定とされています。
確認方法
- 既存プロジェクトを 19 に上げる場合は、まず公式のアップグレードガイドに沿って移行します
forwardRefや<Context.Provider>は当面動作しますが、順次新しい書き方へ寄せていくと保守が楽になります- Actions 系のフック(
useActionState/useFormStatus/useOptimistic)はフォーム中心の画面から試すと効果を実感しやすいです
注意点
- ここで挙げた挙動はバージョンや利用しているフレームワーク(例: Next.js などのメタフレームワーク)によって推奨の使い方が異なる場合があります。最新の公式ドキュメントを一次情報として確認してください
- 楽観的更新やサスペンドを伴う API は、エラー時のフォールバック設計(Error Boundary / Suspense の
fallback)とセットで考える必要があります
まとめ
React 19 は「非同期・フォーム処理の定型コードを減らす」方向の変更が中心です。
- Actions と
useActionState/useFormStatus/useOptimisticでフォーム処理が簡潔に useで Promise・コンテキストを柔軟に読み取りrefがプロップス化しforwardRefが不要に- メタデータ・スタイル・リソース先読みのサポート強化
まずは新規画面や小さなフォームから新 API を試し、徐々に既存コードを寄せていくのがおすすめです。


