発行:

データ更新とAction

読み込みが loader ならば、書き込み(作成・更新・削除)は action<Form> が担当します。これらはHTML標準の挙動を基盤にしており、Reactの状態管理に頼りすぎないシンプルで堅牢なデータ更新フローを提供します。

Actionの定義

Actionは、フォームが送信(サブミット)された際にサーバーサイド(またはクライアントサイドのルーター)で実行される処理です。

requestオブジェクトの活用

Action関数は、送信された内容を含む request オブジェクトを受け取ります。ここから標準の formData() メソッドを使って値を取り出します。

src/NewPost.jsx
import { Form, redirect } from "react-router-dom";

// 1. Action関数(送信処理の実体)
export const createPostAction = async ({ request }) => {
  const formData = await request.formData();

  // inputタグの "name" 属性を指定して取得
  const data = {
    title: formData.get("title"),
    body: formData.get("body"),
  };

  // APIへの送信(疑似コード)
  await fetch("https://example.com/api/posts", {
    method: "POST",
    body: JSON.stringify(data),
  });

  // 処理完了後の移動
  return redirect("/posts");
};

Formコンポーネントの使用

React純正の form ではなく、React Routerの <Form> コンポーネントを使います。これを使うことで、ブラウザの「ページ全体のリロード」を防ぎつつ、ルーティングに統合された送信処理が行われます。

const NewPost = () => {
  return (
    <div className="max-w-xl p-8">
      <h1 className="text-2xl font-bold">新規記事作成</h1>
      <Form method="post" className="mt-6 space-y-4">
        <input
          name="title"
          className="w-full border border-white/10 bg-white/5 p-2"
          required
        />
        <textarea
          name="body"
          className="h-32 w-full border border-white/10 bg-white/5 p-2"
          required
        />
        <button type="submit" className="rounded bg-indigo-600 px-6 py-2">
          投稿
        </button>
      </Form>
    </div>
  );
};

Actionの圧倒的なメリット

宣言的なフォーム管理

useStateonChange を使って一つ一つの入力フィールドを監視する必要はありません。ブラウザ標準の name 属性と formData だけで完結するため、コードが非常に劇的にスッキリします。

自動再検証 (Revalidation) の魔法

Actionが正常に完了(リターンあるいはリダイレクト)すると、React Routerは 現在画面上に表示されているすべてのLoaderデータを自動的に再取得 (Reload) します。

これにより、「記事を作成したのに一覧に戻っても新しい記事が出てこない」といったキャッシュの問題が一切発生しなくなります。常に最新のデータを表示し続けるための同期処理を、ライブラリが肩代わりしてくれます。

まとめ

  • 読むとき : loader
  • 書くとき : action

このシンプルで強力な対称性こそが、最新のReact Router(およびRemix)の核心です。