🐷

React 19 のフォーム周り新機能を試してみた!

に公開

本記事では、2024年末にリリースされたReact19の新機能の中でも、特に「フォーム周り」がどう変わったのかを実際に手を動かしながら試してまとめてみました。

これまでのReactでは、フォーム送信や非同期処理のたびに「Pending用のstateを用意」「エラーハンドリングを自前で書く」「楽観的更新はuseState+手作業で実装…」というボイラープレートがどうしても増えがちでした。
React19では、そのあたりが簡素化・自動化されており、生産性が向上しています。

React19 における「Actions」とその関連フックでフォームがどれだけスッキリ書けるようになったかを紹介していきます。

1. React 19 でフォーム周りは何が変わった?

大きくは以下の2点です。

  1. 非同期関数を“低優先度トランジション”として扱えるようになった

    • startTransition(async () => { … }) のように、非同期処理そのものをトランジションにラップして記述できるようになりました。
    • これにより、データ取得→描画更新の流れを async/await で自然に書けるようになり、UI のブロッキングが少ないコードがシンプルに書けます。
  2. “Actions”+関連フックにより、フォームの非同期送信やエラーハンドリングが自動化・簡略化された

    • これまでは、onSubmit の中で e.preventDefault() をしてから fetchaxiosでリクエスト→setState でローディング/エラー状態を管理といった冗長なコードを書きがちでした。
    • React19 では「Action」という非同期関数を定義し、React側が自動的に「実行中」、「成功」、「失敗」の状態をトラッキングしてくれる仕組みが導入されました。
    • これによって、「Pending中のスピナー表示」「エラー時のメッセージ表示」といった処理を各々自前で書く必要が減っています。

2. 開発者が嬉しいポイント

  • ボイラープレートの大幅削減
    従来はフォーム送信時にuseStateを複数用意して、isLoading/isError/errorMessage を管理していました。React19 では、Action 関数を渡すだけでこれらの状態を自動トラッキングしてくれるので、上述にもあるように記述量が減ります。

  • 可読性の向上
    非同期処理が「どこで」「どんな結果を返すのか」を一箇所の Action 関数にまとめられるので、コンポーネント内のロジックがスリムになります。コードを追うときも「Action の名前を見れば何をしているか分かる」ようになり、チーム開発でもレビューが楽になります。

  • UI/UX の改善
    startTransition(async () => {...})を使えば、重たいAPIコール中でも入力フォームなどを即座に操作可能な状態に保つことが簡単になります。さらに、useOptimistic などのフックを使えば楽観的更新も楽に実装できるため、ボタンを押した瞬間に画面が先に更新されるといったスムーズなUXを実現しやすくなります。

3. 新登場の関連フックを解説

ここからは、実際にフォーム周りでよく使う新しい関連フックを見ていきます。

3.1 useActionState

  • 何をするフック?
    Action=非同期関数を渡すと、その関数を実行する「formAction」と、stateを表すactionStateオブジェクトのペアを返してくれます。

  • メリット
    Actionsで扱った値をすべて React が自動で管理してくれる。従来のように useState を複数用意する必要がないので、コンポーネント内のコードがシンプルになります

  const [actionState, formAction] = useActionState<ActionState, FormData>(
    async (_, formData) => { /* Action定義 */ },
    { success: false }
  );

3.2 useFormStatus の概要

  • 何をするフック?
    <form> 要素に紐づけられた Action をより手軽に監視したいときに使うフックです。useActionState と似ていますが、こちらは「フォームそのもの」にフォーカスして提供されています。
// イメージ
const formStatus = useFormStatus();
// 返り値の例:
{
    pending: true/false;
    data: ~;
    method: ~;
    action: ~;
{
  • メリット
    同じフォーム内で「送信中」、「エラー表示」、「成功時の表示」などをまとめて扱いやすい。

3.3 useOptimistic の概要

  • 何をするフック?
    「楽観的更新」を楽に実装するフックです。 サーバー応答を待つ間に一時的にローカルで状態を更新し、「ユーザーからはもう更新されたように見える」挙動を実現できます。

  • メリット
    サーバー応答前でも画面が先に更新されるため、UXがスムーズに感じられる。
    従来の「useState で一旦setして、サーバーがエラーだったら元に戻す」といった手間を、React側が自動で管理してくれる。今まではuseStateを使用していましたが不要になります。

今回試したコードとリリースURL

4. まとめ React 19 でフォーム開発がどう変わるか

  1. 非同期関数を低優先度トランジション (startTransition(async () => { … })) として直接ラップできるようになった
    重たい処理でも UI のインタラクションが阻害されず、UX が向上します。
  2. “Actions”+新フック(useActionState、useFormStatus、useOptimistic)を使うことで、フォーム送信やエラーハンドリング、楽観的更新を自動トラッキングできるようになった
  • useActionState:Action 関数をラップして「送信中/成功/失敗」の状態を自動管理
  • useFormStatus:<form> 要素に対して送信状態を監視し、フォーム単位で結果を取得できる
  • useOptimistic:サーバー応答前にローカル状態を先に更新し、レスポンス結果に合わせて差分を自動ロールバック

これらの新機能をうまく組み合わせることで、従来は複雑だったフォーム周りのロジックが非常にシンプルかつ直感的に書けるようになります。実際に開発を進めてみると、ビジネスロジックのコア部分に集中でき、チーム全体でクオリティの高いフォーム体験を提供しやすくなるかもしれません。

もしまだ React19にアップグレードしていないプロジェクトがあれば、フォーム周りのボイラープレートから解放され、より生産性の高い開発を試してみてください。

GAOGAO Engineer Blog

Discussion