OpenAIReact2024/12/05 0:00

React v19

要点だけを先に読めるように短く再構成したセクションです。

元記事

Quick Digest

要約

要点だけを先に読めるように短く再構成したセクションです。

openaijamodel: gpt-5-mini-2025-08-07

React v19 正式リリース(2024-12-05)

Key Points

  • Actionsで非同期遷移を簡素化
  • useでSuspenseと統合
  • prerenderで静的出力を強化

Summary

React v19 が安定版として公開されました(2024-12-05)。本リリースは Actions(非同期遷移の標準化)、新しいフック群(useActionState、useOptimistic、use)、react-dom の <form> Actions と useFormStatus、react-dom/static の prerender APIs、Server Components の改善などを含みます。アップグレード手順や破壊的変更は公式の Upgrade Guide を必ず確認してください。

Key Points

  • Actions
    • async 関数を遷移として使えるようになり、pending/エラー/楽観更新を自動管理。
    • startTransition を使った遷移の簡素化と、フォームの action に関数を渡すだけで自動送信が可能。
  • useActionState
    • Action のラップ版を返し、直近の結果(data)と pending 状態を簡単に扱える。フォーム連携に便利。
  • useOptimistic
    • 楽観的な UI 更新を即時表示し、リクエスト完了時に自動で差し戻し/確定を行う。
  • use
    • レンダリング中に Promise や Context を読み取り Suspense と統合(レンダ内で生成した Promise はサポート外/警告)。
  • react-dom のフォーム改善
    • <form>/<input>/<button> の action/formAction に関数を渡すと Actions を使った自動送信・フォームリセットが可能。
    • useFormStatus で親フォームの pending 状態をコンポーネント側から取得できる。
  • react-dom/static
    • prerender / prerenderToNodeStream により、データを待ってから静的 HTML を生成(ストリーム環境向け)。
  • Server Components
    • ビルド時またはリクエスト時に別環境でレンダ可能。カナリアで導入された機能を取り込み済み。

Upgrade notes

  • まず npm で react@19 / react-dom@19 に更新し、Upgrade Guide の破壊的変更リストを確認してください。
  • 既存のフォームや非同期処理は段階的に Actions / useActionState / useOptimistic に移行可能。
  • Suspense 周りは Promise の生成場所に注意(レンダ内での新規 Promise 作成は避ける)。

Full Translation

翻訳

原文の流れを保ったまま読める翻訳セクションです。

openaijamodel: gpt-5-mini-2025-08-07

React v19 リリース

React v19 リリース

公開日: 2024-12-05

by The React Team

注: React 19 は安定版になりました!

本投稿は 2024年4月 に公開された React 19 RC の内容からの追加を含みます。

  • サスペンドされたツリーの事前ウォーム: Improvements to Suspense を参照
  • React DOM の static API: New React DOM Static APIs を参照

日付は安定リリース日に合わせて更新しています。

React v19 は npm で利用可能です。React 19 へのアップグレード手順は React 19 Upgrade Guide にステップバイステップでまとめています。この投稿では React 19 の新機能の概要と採用方法を説明します。

目次

  • What’s new in React 19
  • Improvements in React 19
  • How to upgrade

破壊的変更の一覧は Upgrade Guide を参照してください。

React 19 の新機能

Actions

React アプリでよくあるユースケースは、データを変更(mutation)して、その結果に応じて状態を更新することです。たとえばユーザーが名前を変更するフォームを送信した際に API リクエストを送り、応答を処理します。従来は未了状態(pending)、エラー、楽観的更新(optimistic updates)、順次リクエストなどを手動で扱う必要がありました。例えば useState を使って未了やエラーを管理する例:

// Before Actions
function UpdateName({}) {
  const [name, setName] = useState("");
  const [error, setError] = useState(null);
  const [isPending, setIsPending] = useState(false);
  const handleSubmit = async () => {
    setIsPending(true);
    const error = await updateName(name);
    setIsPending(false);
    if (error) {
      setError(error);
      return;
    }
    redirect("/path");
  };
  return (
    <div>
      <input value={name} onChange={(event) => setName(event.target.value)} />
      <button onClick={handleSubmit} disabled={isPending}>Update</button>
      {error && <p>{error}</p>}
    </div>
  );
}

React 19 では、遷移(transition)内で async 関数を使えるようにして、未了状態・エラー・フォーム・楽観的更新を自動で扱えるようにしています。たとえば useTransition を使って未了状態を処理する例:

// Using pending state from Actions
function UpdateName({}) {
  const [name, setName] = useState("");
  const [error, setError] = useState(null);
  const [isPending, startTransition] = useTransition();
  const handleSubmit = () => {
    startTransition(async () => {
      const error = await updateName(name);
      if (error) {
        setError(error);
        return;
      }
      redirect("/path");
    })
  };
  return (
    <div>
      <input value={name} onChange={(event) => setName(event.target.value)} />
      <button onClick={handleSubmit} disabled={isPending}>Update</button>
      {error && <p>{error}</p>}
    </div>
  );
}

この async 遷移は即座に isPending を true にし、非同期リクエストを実行し、遷移が完了して最終ステート更新がコミットされると isPending を false に戻します。これによりデータ変更中も現在の UI を応答可能・操作可能に保てます。

注: async 遷移を使う関数は慣例として “Actions” と呼ばれます。

Actions は以下を自動で管理します:

  • Pending state: リクエスト開始時に pending 状態になり、最終的な状態更新がコミットされると自動でリセットされます。
  • Optimistic updates: useOptimistic フックとの連携をサポートし、送信中に即時フィードバックを表示できます。
  • Error handling: リクエストが失敗したときに Error Boundary を表示したり、楽観的更新を元に戻したりできます。
  • Forms: <form> 要素は action と formAction props に関数を渡すことをサポートします。action に関数を渡すとデフォルトで Actions を使い、送信後に自動でフォームをリセットします。

Actions の上に構築された新機能として、React 19 では楽観的更新を管理する useOptimistic と、Actions の一般的なケースを扱うための新フック React.useActionState を導入しています。react-dom ではフォームを自動管理する <form> Actions と、フォーム内での典型的ユースケースをサポートする useFormStatus を追加しました。

前述の例は React 19 では次のように簡略化できます:

// Using <form> Actions and useActionState
function ChangeName({ name, setName }) {
  const [error, submitAction, isPending] = useActionState(async (previousState, formData) => {
    const error = await updateName(formData.get("name"));
    if (error) {
      return error;
    }
    redirect("/path");
    return null;
  }, null);
  return (
    <form action={submitAction}>
      <input type="text" name="name" />
      <button type="submit" disabled={isPending}>Update</button>
      {error && <p>{error}</p>}
    </form>
  );
}

次のセクションで React 19 の Actions の各機能を詳しく説明します。

新しいフック: useActionState

Actions の一般的なケースを簡単にするため、useActionState という新しいフックを追加しました:

const [error, submitAction, isPending] = useActionState(async (previousState, newName) => {
  const error = await updateName(newName);
  if (error) {
    // Action の結果は何でも返せます。
    // この例ではエラーだけ返します。
    return error;
  }
  // 成功時の処理
  return null;
}, null);

useActionState は関数(“Action”)を受け取り、呼び出すためのラップされた Action を返します。これは Action が合成可能であるため機能します。ラップされた Action が呼ばれると、useActionState は Action の最後の結果を data として、Action の pending 状態を pending として返します。

注: React.useActionState は Canary リリースでは以前 ReactDOM.useFormState と呼ばれていましたが、名前を変更し useFormState を非推奨にしました。詳細は #28491 を参照してください。

詳しくは useActionState のドキュメントを参照してください。

React DOM: <form> Actions

Actions は react-dom の新しい <form> 機能とも統合されています。<form>, <input>, <button> の action と formAction props に関数を渡すことで、Actions を使ってフォームを自動送信できます:

<form action={actionFunction}>
<form> Action が成功すると、React はアンコントロールコンポーネント(uncontrolled components)のフォームを自動でリセットします。手動でリセットする必要がある場合は、新しい requestFormReset React DOM API を呼び出せます。詳細は react-dom の <form>, <input>, <button> のドキュメントを参照してください。

React DOM: 新しいフック useFormStatus

デザインシステムでは、コンポーネントにフォームの状態情報を渡すために props を深く渡さずに済ませたいことがよくあります。Context を使えば可能ですが、一般的なケースを簡単にするために新しいフック useFormStatus を追加しました:

import { useFormStatus } from 'react-dom';
function DesignButton() {
  const { pending } = useFormStatus();
  return <button type="submit" disabled={pending} />;
}

useFormStatus は親 <form> の状態をあたかも Context プロバイダのように読み取ります。詳細は react-dom の useFormStatus のドキュメントを参照してください。

新しいフック: useOptimistic

データの変更中に最終状態を楽観的に表示するパターンはよくあります。React 19 ではこれを簡単にする useOptimistic を追加しました:

function ChangeName({ currentName, onUpdateName }) {
  const [optimisticName, setOptimisticName] = useOptimistic(currentName);
  const submitAction = async formData => {
    const newName = formData.get("name");
    setOptimisticName(newName);
    const updatedName = await updateName(newName);
    onUpdateName(updatedName);
  };
  return (
    <form action={submitAction}>
      <p>Your name is: {optimisticName}</p>
      <p>
        <label>Change Name:</label>
        <input type="text" name="name" disabled={currentName !== optimisticName} />
      </p>
    </form>
  );
}

useOptimistic は updateName リクエストが完了するまで optimisticName を即座にレンダリングします。更新が成功・失敗すると React は自動的に currentName に戻します。詳細は useOptimistic のドキュメントを参照してください。

新しい API: use

React 19 では、レンダー内でリソースを読み取るための新しい API use を導入します。例えば Promise を use で読み取ると、Promise が解決されるまで React がサスペンドします:

import { use } from 'react';
function Comments({ commentsPromise }) {
  // `use` は promise が解決されるまでサスペンドします。
  const comments = use(commentsPromise);
  return comments.map(comment => <p key={comment.id}>{comment}</p>);
}
function Page({ commentsPromise }) {
  // Comments 内で `use` がサスペンドすると、
  // この Suspense boundary が表示されます。
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Comments commentsPromise={commentsPromise} />
    </Suspense>
  );
}

注意: use は render 内で作られた Promise をサポートしません。render 内で作成された Promise を use に渡すと、次のような警告が出ます:

Console
A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.

修正するには、Promise のキャッシュをサポートする Suspense 対応のライブラリ/フレームワークから渡される Promise を use に渡す必要があります。将来的には render 内で Promise をキャッシュしやすくする機能を追加する予定です。

また use を使って Context を読み取ることもでき、早期 return の後など条件付きで Context を取得できます:

import { use } from 'react';
import ThemeContext from './ThemeContext';
function Heading({ children }) {
  if (children == null) {
    return null;
  }
  // useContext では早期 return のために動かないケースでも、
  // `use` なら条件付きで Context を読むことができます。
  const theme = use(ThemeContext);
  return <h1 style={{ color: theme.color }}>{children}</h1>;
}

use API はフックと同様にレンダーでのみ呼び出せます。フックとは異なり、条件付きで呼び出すことが可能です。将来的に use でレンダー中にリソースを消費するためのより多くの方法をサポートする予定です。詳細は use のドキュメントを参照してください。

新しい React DOM Static APIs

静的サイト生成のために react-dom/static に 2 つの新しい API を追加しました:

  • prerender
  • prerenderToNodeStream

これらは renderToString を改良したもので、静的 HTML 生成時にデータの読み込みを待機します。Node.js Streams や Web Streams のようなストリーミング環境で動作するように設計されています。たとえば Web Stream 環境では prerender を使って React ツリーを静的 HTML にプリレンダリングできます:

import { prerender } from 'react-dom/static';
async function handler(request) {
  const { prelude } = await prerender(<App />, { bootstrapScripts: ['/main.js'] });
  return new Response(prelude, { headers: { 'content-type': 'text/html' } });
}

Prerender API は静的な HTML を返す前にすべてのデータ読み込みを待ちます。ストリームは文字列に変換することも、ストリーミングレスポンスとして送ることも可能です。これらは読み込みに合わせて段階的にストリーミングするのではなく、データを待ってから静的 HTML を生成します。ストリーミングを段階的に行いたい場合は既存の React DOM server rendering APIs を利用してください。詳細は React DOM Static APIs を参照してください。

React Server Components

Server Components は、クライアントアプリや SSR サーバーとは別の環境で、バンドル前にコンポーネントを先にレンダリングできる新しいオプションです。この別環境が React Server Components における “サーバー” です。Server Components は CI サーバー上でビルド時に一度だけ実行することも、ウェブサーバーで各リクエストごとに実行することもできます。

React 19 には Canary チャンネルから提供されていた Server Components の機能がすべて含まれています。つまり Server Compone

(注: ソースはここで途中で切れています。続きは公式ドキュメントを参照してください。)