フォーム検証

フォーム検証

このガイドでは、簡単なサインアップフォームの実装について説明します。これらの概念をサードパーティの検証ライブラリやエラーコンポーネントと組み合わせることをお勧めしますが、このガイドではReact Routerの可動部分にのみ焦点を当てています。

1. セットアップ

まず、フォームを含む基本的なサインアップルートを作成します。

import {
  type RouteConfig,
  route,
} from "@react-router/dev/routes";

export default [
  route("signup", "signup.tsx"),
] satisfies RouteConfig;
import type { Route } from "./+types/signup";
import { useFetcher } from "react-router";

export default function Signup(_: Route.ComponentProps) {
  let fetcher = useFetcher();
  return (
    <fetcher.Form method="post">
      <p>
        <input type="email" name="email" />
      </p>

      <p>
        <input type="password" name="password" />
      </p>

      <button type="submit">Sign Up</button>
    </fetcher.Form>
  );
}

2. アクションの定義

このステップでは、Signupコンポーネントと同じファイルにサーバー側のactionを定義します。ここでの目的は、フォーム検証ルールやエラーオブジェクト構造を深く掘り下げるのではなく、関連するメカニズムの概要を示すことです。コアな概念を示すために、メールアドレスとパスワードの基本的なチェックを使用します。

import type { Route } from "./+types/signup";
import { redirect, useFetcher, data } from "react-router";

export default function Signup(_: Route.ComponentProps) {
  // omitted for brevity
}

export async function action({
  request,
}: Route.ActionArgs) {
  const formData = await request.formData();
  const email = String(formData.get("email"));
  const password = String(formData.get("password"));

  const errors = {};

  if (!email.includes("@")) {
    errors.email = "Invalid email address";
  }

  if (password.length < 12) {
    errors.password =
      "Password should be at least 12 characters";
  }

  if (Object.keys(errors).length > 0) {
    return data({ errors }, { status: 400 });
  }

  // Redirect to dashboard if validation is successful
  return redirect("/dashboard");
}

検証エラーが見つかった場合、それらはactionからフェッチャーに返されます。これは、UIに修正が必要であることを知らせるための方法であり、そうでない場合は、ユーザーがダッシュボードにリダイレクトされます。

data({ errors }, { status: 400 }) という呼び出しに注目してください。400 ステータスを設定することは、クライアントにバリデーションエラーがあった(Bad Request)ことを知らせるためのウェブ標準的な方法です。React Router では、200 ステータスコードのみがページデータの再検証をトリガーするため、400 はそれを防ぎます。

3. バリデーションエラーの表示

最後に、Signup コンポーネントを修正して、fetcher.data からのバリデーションエラーがあれば表示するようにします。

export default function Signup(_: Route.ComponentProps) {
  let fetcher = useFetcher();
  let errors = fetcher.data?.errors;
  return (
    <fetcher.Form method="post">
      <p>
        <input type="email" name="email" />
        {errors?.email ? <em>{errors.email}</em> : null}
      </p>

      <p>
        <input type="password" name="password" />
        {errors?.password ? (
          <em>{errors.password}</em>
        ) : null}
      </p>

      <button type="submit">Sign Up</button>
    </fetcher.Form>
  );
}
ドキュメントと例 CC 4.0