Valibot スキーマ / conformValibotMessage

conformValibotMessage

検証動作を制御するためのカスタムメッセージのセットです。これは、フィールドの一つに対して非同期検証が必要な場合に便利です。

#Options

conformValibotMessage.VALIDATION_SKIPPED

このメッセージは、検証がスキップされ、 Conform が前回の結果を代わりに使用すべきであることを示すために使用されます。

conformValibotMessage.VALIDATION_UNDEFINED

このメッセージは、検証が定義されていないことを示し、 Conform がサーバー検証にフォールバックすべきであることを示すために使用されます。

#Example

検証をスキップして、以前の結果を使用できます。クライアント検証では、検証が定義されていないことを示すことで、サーバー検証にフォールバックできます。

1import type { Intent } from '@conform-to/react';
2import { useForm } from '@conform-to/react';
3import { parseWithValibot, conformValibotMessage } from '@conform-to/valibot';
4import {
5  check,
6  forward,
7  forwardAsync,
8  object,
9  partialCheck,
10  partialCheckAsync,
11  pipe,
12  pipeAsync,
13  string,
14} from 'valibot';
15
16function createBaseSchema(intent: Intent | null) {
17  return object({
18    email: pipe(
19      string('Email is required'),
20      // メールアドレスを検証しない場合は、メールエラーをそのままにしておきます。
21      check(
22        () =>
23          intent === null ||
24          (intent.type === 'validate' && intent.payload.name === 'email'),
25        conformValibotMessage.VALIDATION_SKIPPED,
26      ),
27    ),
28    password: string('Password is required'),
29  });
30}
31
32function createServerSchema(
33  intent: Intent | null,
34  options: { isEmailUnique: (email: string) => Promise<boolean> },
35) {
36  return pipeAsync(
37    createBaseSchema(intent),
38    forwardAsync(
39      partialCheckAsync(
40        [['email']],
41        async ({ email }) => options.isEmailUnique(email),
42        'Email is already used',
43      ),
44      ['email'],
45    ),
46  );
47}
48
49function createClientSchema(intent: Intent | null) {
50  return pipe(
51    createBaseSchema(intent),
52    forward(
53      // メールアドレスが指定されている場合は、その一意性をチェックするためにサーバー検証にフォールバックします。
54      partialCheck(
55        [['email']],
56        () => false,
57        conformValibotMessage.VALIDATION_UNDEFINED,
58      ),
59      ['email'],
60    ),
61  );
62}
63
64export async function action({ request }) {
65  const formData = await request.formData();
66  const submission = await parseWithValibot(formData, {
67    schema: (intent) =>
68      createServerSchema(intent, {
69        isEmailUnique: async (email) => {
70          // データベースを参照して、メールアドレスが一意であるかどうかを確認します
71        },
72      }),
73  });
74
75  // ステータスが成功でない場合は、送信内容をクライアントに送り返します
76  if (submission.status !== 'success') {
77    return submission.reply();
78  }
79
80  // ...
81}
82
83function ExampleForm() {
84  const [form, { email, password }] = useForm({
85    onValidate({ formData }) {
86      return parseWithValibot(formData, {
87        schema: (intent) => createClientSchema(intent),
88      });
89    },
90  });
91
92  // ...
93}