Future APIs / useIntent

useIntent

The useIntent function is part of Conform's future export. These APIs are experimental and may change in minor versions. Learn more

A React hook that provides an intent dispatcher for programmatic form actions. Intent dispatchers allow you to trigger form operations like validation, field updates, and array manipulations without manual form submission.

import { useIntent } from '@conform-to/react/future';

const intent = useIntent(formRef);

#Parameters

formRef: FormRef

A reference to the form element. Can be either:

  • A React ref object pointing to a form element (e.g. React.RefObject<HTMLFormElement>, React.RefObject<HTMLButtonElement>, React.RefObject<HTMLInputElement>).
  • A form ID string to target a specific form

#Returns

An IntentDispatcher object with the following methods:

validate(name?: string): void

Triggers validation for the entire form or a specific field. If you provide a name that includes nested fields (e.g. user.email), it will validate all fields within that fieldset.

  • name (optional): Field name to validate. If omitted, validates the entire form.

reset(): void

Resets the form to its initial state, clearing all values and validation states.

update(options): void

Updates a field or fieldset with new values.

  • options.name (optional): Field name to update. If omitted, updates the entire form.
  • options.index (optional): Array index when updating array fields.
  • options.value: New value for the field or fieldset.

insert(options): void

Inserts a new item into an array field.

  • options.name: Name of the array field.
  • options.index (optional): Position to insert at. If omitted, appends to the end.
  • options.defaultValue (optional): Default value for the new item.

remove(options): void

Removes an item from an array field.

  • options.name: Name of the array field.
  • options.index: Index of the item to remove.

reorder(options): void

Reorders items within an array field.

  • options.name: Name of the array field.
  • options.from: Current index of the item.
  • options.to: Target index to move the item to.

#Examples

Reusable reset button

1import { useRef } from 'react';
2import { useIntent, useForm } from '@conform-to/react/future';
3
4function ResetButton() {
5  const buttonRef = useRef<HTMLButtonElement>(null);
6  const intent = useIntent(buttonRef);
7
8  return (
9    <button type="button" ref={buttonRef} onClick={() => intent.reset()}>
10      Reset Form
11    </button>
12  );
13}
14
15function MyForm() {
16  const { form } = useForm({
17    // ...
18  });
19
20  return (
21    <form {...form.props}>
22      <input name="email" type="email" />
23      <input name="password" type="password" />
24      <button>Submit</button>
25      <ResetButton />
26    </form>
27  );
28}

Enter key to add array item

1import { useRef } from 'react';
2import { useIntent, useForm } from '@conform-to/react/future';
3
4function TagInput({ name }: { name: string }) {
5  const inputRef = useRef<HTMLInputElement>(null);
6  const intent = useIntent(inputRef);
7
8  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
9    if (e.key === 'Enter' && e.currentTarget.value.trim()) {
10      e.preventDefault();
11      intent.insert({
12        name,
13        defaultValue: e.currentTarget.value.trim(),
14      });
15      e.currentTarget.value = '';
16    }
17  };
18
19  return (
20    <input
21      ref={inputRef}
22      type="text"
23      placeholder="Type and press Enter to add..."
24      onKeyDown={handleKeyDown}
25    />
26  );
27}
28
29function MyForm() {
30  const { form, fields } = useForm({
31    defaultValue: {
32      tags: ['react', 'forms'],
33    },
34  });
35  const tagFields = fields.tags.getFieldList();
36
37  return (
38    <form {...form.props}>
39      <div>
40        <label>Tags</label>
41        <div>
42          {tagFields.map((tag, index) => (
43            <span key={tag.key}>
44              <input
45                type="hidden"
46                name={tag.name}
47                defaultValue={tag.defaultValue}
48              />
49              {tag.defaultValue}
50            </span>
51          ))}
52        </div>
53        <TagInput name="tags" />
54      </div>
55      <button>Submit</button>
56    </form>
57  );
58}

#Tips

External buttons with form association

You can create intent buttons outside the form using the form attribute:

1import { useRef } from 'react';
2import { useIntent, useForm } from '@conform-to/react/future';
3
4function ResetButton({ form }: { form?: string }) {
5  const buttonRef = useRef<HTMLButtonElement>(null);
6  const intent = useIntent(buttonRef);
7
8  return (
9    <button
10      type="button"
11      ref={buttonRef}
12      form={form}
13      onClick={() => intent.reset()}
14    >
15      Reset Form
16    </button>
17  );
18}
19
20function MyApp() {
21  const { form, fields } = useForm({
22    // ...
23  });
24
25  return (
26    <>
27      <form {...form.props}>
28        <input name="title" />
29        <input name="description" />
30        <button type="submit">Submit</button>
31      </form>
32
33      {/* Button associated via form attribute */}
34      <ResetButton form={form.id} />
35    </>
36  );
37}