ガイド / インテントボタン

インテントボタン

送信ボタンがフォームの送信を行う際、それは submitter として機能し、フォームデータに含まれることになります。

#送信のインテント

submitter は、インテント(意図)に基づいて異なる振る舞いでフォームを拡張したい場合に特に便利です。

1import { useForm } from '@conform-to/react';
2
3function Product() {
4  const [form] = useForm({
5    onSubmit(event, { formData }) {
6      event.preventDefault();
7
8      switch (formData.get('intent')) {
9        case 'add-to-cart':
10          // カートに追加
11          break;
12        case 'buy-now':
13          // 購入
14          break;
15      }
16    },
17  });
18
19  return (
20    <form id={form.id}>
21      <input type="hidden" name="productId" value="rf23g43" />
22      <button type="submit" name="intent" value="add-to-cart">
23        Add to Cart
24      </button>
25      <button type="submit" name="intent" value="buy-now">
26        Buy now
27      </button>
28    </form>
29  );
30}

#フォームのコントロール

Conform は、フィールドのバリデーションや削除など、すべてのフォームコントロールに対して送信のインテントを利用します。これは、ボタンに予約された名前を与え、インテントを値としてシリアライズすることで成されます。設定を簡素化するために、 Conform は form.validateform.resetform.insert などの一連のフォームコントロールヘルパーを提供します。

バリデート インテント

バリデーションをトリガーするには、バリデート インテントを使用してボタンを構成できます。

1import { useForm } from '@conform-to/react';
2
3function EmailForm() {
4  const [form, fields] = useForm();
5
6  return (
7    <form id={form.id}>
8      <input name={fields.email.name} />
9      <button {...form.validate.getButtonProps({ name: fields.email.name })}>
10        Validate Email
11      </button>
12    </form>
13  );
14}

ボタンがクリックされると、 Conform は予約された名前でシリアライズされたインテントを識別し、メールフィールドを検証済みとしてマークすることによりバリデーションをトリガーし、メールが無効である場合はエラーメッセージを返します。

しかし、ユーザーがフィールドを離れた時点でバリデーションをトリガーしたい場合は、バリデート インテントを直接トリガーすることもできます。

1import { useForm } from '@conform-to/react';
2
3function EmailForm() {
4  const [form, fields] = useForm();
5
6  return (
7    <form id={form.id}>
8      <input
9        name={fields.email.name}
10        onBlur={(event) => form.validate({ name: event.target.name })}
11      />
12    </form>
13  );
14}

reset および update インテント

reset および update のインテントを使ってフィールドを変更することもできます。

1import { useForm } from '@conform-to/react';
2
3export default function Tasks() {
4  const [form, fields] = useForm();
5
6  return (
7    <form id={form.id}>
8      <button {...form.reset.getButtonProps()}>Reset form</button>
9      <button
10        {...form.reset.getButtonProps({
11          name: fields.tasks.name,
12        })}
13      >
14        Reset field (including nested / list field)
15      </button>
16      <button
17        {...form.update.getButtonProps({
18          name: fields.agenda.name,
19          value: {
20            title: 'My agenda',
21            description: 'This is my agenda',
22          },
23        })}
24      >
25        Update field (including nested / list field)
26      </button>
27      <button
28        {...form.update.getButtonProps({
29          validated: false,
30        })}
31      >
32        Clear all error
33      </button>
34    </form>
35  );
36}

両方のインテントを使用するには、フィールドメタデータから key を使って入力を設定する必要があります。 Conform はこのキーに依存して、更新された initialValue で input を再マウントするための React への通知を行います。唯一の例外は、 useInputControl フックを使用して制御された入力を設定している場合で、 key が変更されると値がリセットされます。

insert、remove、および reorder (並び替え) インテント

フィールドリストを操作するには、 insertremovereorder のインテントを使用できます。

1import { useForm } from '@conform-to/react';
2
3export default function Tasks() {
4  const [form, fields] = useForm();
5  const tasks = fields.tasks.getFieldList();
6
7  return (
8    <form id={form.id}>
9      <ul>
10        {tasks.map((task, index) => (
11          <li key={task.key}>
12            <input name={task.name} />
13            <button
14              {...form.reorder.getButtonProps({
15                name: fields.tasks.name,
16                from: index,
17                to: 0,
18              })}
19            >
20              Move to top
21            </button>
22            <button
23              {...form.remove.getButtonProps({
24                name: fields.tasks.name,
25                index,
26              })}
27            >
28              Delete
29            </button>
30          </li>
31        ))}
32      </ul>
33      <button
34        {...form.insert.getButtonProps({
35          name: fields.tasks.name,
36        })}
37      >
38        Add task
39      </button>
40      <button>Save</button>
41    </form>
42  );
43}