React 19 の新機能まとめ(入門)

概要

React 19 は 2024 年 12 月に安定版がリリースされたメジャーバージョンです。フォーム処理まわりを大きく変える「Actions」、非同期処理をシンプルに扱う use API、forwardRef を不要にする ref の扱いの変更など、日々の実装に効く変更が多く入っています。

この記事では「まず何が変わったのか」を入門者向けに整理します。個別 API の細かい仕様は公式ドキュメントに譲り、全体像をつかむことを目的にします。

React 19 フォーム / 非同期 データ読み取り DX / メタ管理 Actions (useTransition) useActionState useFormStatus useOptimistic use(promise) use(context) ※ 条件分岐内でも呼べる ref を props で受取 ref クリーンアップ <title>/<meta> 自動head preload / preinit <Context> を直接使用
図1: React 19 の新機能マップ(本記事で扱う範囲)

環境

  • React 19(安定版)
  • 記載のコードは概念を示すための最小例です

主な新機能

送信form action useActionStateisPending=true useOptimisticUIを先に更新 サーバー処理await submit() 結果を state へisPending=false
図2: Actions を使ったフォーム処理の流れ(保留状態・楽観的更新が自動化される)

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 を試し、徐々に既存コードを寄せていくのがおすすめです。

\ 最新情報をチェック /

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください