バリデーション

仕組み

Inertia におけるサーバーサイドのバリデーションエラーの扱いは、422 レスポンスを受け取ってバリデーションエラーを捕捉し、手動でフォームのエラー状態を更新する必要がある従来の XHR 駆動フォームとは異なります。というのも、Inertia は 422 レスポンスを受信しないからです。その代わり、Inertia は標準的なフルページのフォーム送信に非常に近い形で動作します。以下がその流れです。

まず、Inertia を使ってフォームを送信 します。サーバーサイドでバリデーションエラーが発生した場合、それらのエラーを 422 の JSON レスポンスとして返すのではありません。代わりに、サーバー側でユーザーを直前にいたフォームページへリダイレクトし、バリデーションエラーをセッションにフラッシュします。Laravel などの一部のフレームワークでは、これは自動的に行われます。

次に、これらのバリデーションエラーがセッションに存在する場合、それらは自動的に Inertia と共有され、ページの props としてクライアントサイドから利用可能になります。props はリアクティブであるため、フォーム送信が完了した時点で自動的に表示されます。

最後に、Inertia アプリは 422 レスポンスを生成しないため、レスポンスにバリデーションエラーが含まれているかどうかを判断する別の方法が必要です。これを実現するために、Inertia は page.props.errors オブジェクトにエラーが存在するかどうかをチェックします。エラーが存在する場合、onSuccess() コールバックの代わりに、リクエストの onError() コールバックが呼び出されます。

エラーの共有

サーバーサイドのバリデーションエラーをクライアントサイドで利用できるようにするには、サーバーサイドのフレームワークがそれらを errors prop として共有する必要があります。Laravel アダプターなどの Inertia のファーストパーティ製アダプターは、これを自動的に行います。他のフレームワークの場合は、手動で設定する必要があるかもしれません。詳細については、使用しているサーバーサイドアダプターのドキュメントを参照してください。

エラーの表示

バリデーションエラーはページコンポーネントの props としてクライアントサイドで利用可能になるため、その存在に基づいて条件付きで表示できます。ファーストパーティのサーバーアダプター(Laravel アダプターなど)を使用している場合、errors prop は自動的にページで利用可能になる点に注意してください。

Vue アダプターを使用している場合は、$page.props.errors オブジェクト経由でもエラーにアクセスできます。

フィールドごとの複数エラー

デフォルトでは、Inertia の Laravel アダプターは各フィールドにつき最初のバリデーションエラーのみを返します。すべてのエラーを受け取りたい場合は、ミドルウェアで $withAllErrors プロパティを true に設定することで有効化できます。

php
class HandleInertiaRequests extends Middleware
{
    protected $withAllErrors = true;

    // ...
}

有効にすると、各フィールドには単一の文字列ではなく、エラー文字列の配列が含まれるようになります。

文字列ではなく配列を想定するように、TypeScript を設定 することもできます。

入力値の再設定

Inertia におけるエラー処理はフルページのフォーム送信と似ていますが、Inertia にはさらに多くの利点があります。実際、古いフォーム入力データを手動で再設定する必要すらありません。

バリデーションエラーが発生すると、ユーザーは通常、直前にいたフォームページへリダイレクトされます。そしてデフォルトでは、Inertia は postputpatchdelete リクエストに対して コンポーネントの状態 を自動的に保持します。そのため、ユーザーがフォームを送信した時点の入力データは、そのまま正確に保持されます。

つまり、残る作業は errors prop を使ってバリデーションエラーを表示することだけです。

エラーバッグ

フォームヘルパー を使用している場合、バリデーションエラーはリクエストを行ったフォームオブジェクトに自動的にスコープされるため、エラーバッグを使用する必要はありません。

1 つのページに複数のフォームがある場合、2 つのフォームが同じフィールド名を共有していると、バリデーションエラーの表示時に競合が発生する可能性があります。たとえば、「会社を作成する」フォームと「ユーザーを作成する」フォームの両方に name フィールドがあるとします。両方のフォームが page.props.errors.name のバリデーションエラーを表示するため、どちらか一方のフォームで name フィールドのバリデーションエラーが発生すると、両方のフォームにエラーが表示されてしまいます。

この問題を解決するために、「エラーバッグ」を使用できます。エラーバッグは、サーバーから返されるバリデーションエラーを、そのフォーム固有の一意なキーの下にスコープします。先ほどの例を続けると、最初のフォームには createCompany エラーバッグを、2 つ目のフォームには createUser エラーバッグを使用できます。

エラーバッグを指定すると、バリデーションエラーは page.props.errors.createCompany および page.props.errors.createUser 内に含まれてサーバーから返されます。