Ariakit
/

useFormStore

Creates a form store to control the state of Form components.

Code examples

const form = useFormStore({
email: "",
},
});
<Form store={form}>
<FormLabel name={form.names.email}>Email</FormLabel>
<FormInput name={form.names.email} />
<FormError name={form.names.email} />
</Form>

Optional Props


defaultErrors

DeepPartial<DeepMap<T, ErrorMessage>> | undefined

The default errors of the form.


defaultItems

T[] | undefined = []

The default value for the items state.


defaultTouched

DeepPartial<DeepMap<T, boolean>> | undefined

The default touched state of the form.


defaultValues

T | undefined = {}

The default values of the form.


errors

DeepPartial<DeepMap<T, ErrorMessage>>

Form errors.


items

T[]

Lists all items along with their metadata. This state is automatically updated when an item is registered or unregistered using the registerItem function.

Live examples


setErrors

((errors: DeepPartial<DeepMap<T, ErrorMessage>>) => void) | undefined

Function that will be called when the errors state changes.

Code examples

useFormStore({ setErrors: (errors) => console.log(errors) });

setItems

BivariantCallback<(items: T[]) => void> | undefined

A callback that gets called when the items state changes.

Code examples

const [items, setItems] = useState([]);
const collection = useCollectionStore({ items, setItems });

setTouched

((touched: DeepPartial<DeepMap<T, boolean>>) => void) | undefined

Function that will be called when the touched state changes.

Code examples

useFormStore({ setTouched: (touched) => console.log(touched) });

setValues

((values: T) => void) | undefined

Function that will be called when values state changes.

Code examples

function MyForm({ values, onChange }) {
const form = useFormStore({ values, setValues: onChange });
}

store

Store<Partial<S>> | undefined

Another store object that will be kept in sync with the original store.

Live examples


touched

DeepPartial<DeepMap<T, boolean>>

The touched state of the form.


values

T = {}

Form values.

Live examples

Return Props


getError

(name: StringLike) => ErrorMessage

Retrieves a field error.

Code examples

const nameError = store.getError("name");
// Can also use store.names for type-safety.
const emailError = store.getError(store.names.email);

getFieldTouched

(name: StringLike) => boolean

Retrieves a field touched state.

Code examples

const nameTouched = store.getFieldTouched("name");
// Can also use store.names for type-safety.
const emailTouched = store.getFieldTouched(store.names.email);

getState

() => S

Returns the current store state.


getValue

<T = any>(name: StringLike) => T

Retrieves a field value.

Live examples

Code examples

const nameValue = store.getValue("name");
// Can also use store.names for type-safety.
const emailValue = store.getValue(store.names.email);

item

(id: string | null | undefined) => T | null

Gets an item by its id.

Live examples

Code examples

const item = store.item("item-1");

names

Names<T>

An object containing the names of the form fields for type safety.

Live examples

Code examples

store.names.name; // "name"
store.names.name.first; // "name.first"
store.names.name.last; // "name.last"

onSubmit

(callback: FormStoreCallback<FormStoreState<T>>) => () => void

Function that accepts a callback that will be used to submit the form when submit is called. It returns a cleanup function that will remove the callback.

Code examples

const cleanup = store.onSubmit(async (state) => {
try {
await api.submit(state.values);
} catch (errors) {
store.setErrors(errors);
}
});

onValidate

(callback: FormStoreCallback<FormStoreState<T>>) => () => void

Function that accepts a callback that will be used to validate the form when validate is called. It returns a cleanup function that will remove the callback.

Code examples

const cleanup = store.onValidate(async (state) => {
const errors = await api.validate(state.values);
if (errors) {
store.setErrors(errors);
}
});

pushValue

<T>(name: StringLike, value: T) => void

Pushes a value to an array field.

Code examples

store.pushValue("tags", "new tag");
store.pushValue("tags", { id: 1, name: "new tag" });
// Can also use store.names for type-safety.
store.pushValue(store.names.tags, "new tag");

registerItem

BivariantCallback<(item: T) => () => void>

Registers an item in the collection. This function returns a cleanup function that unregisters the item.

Code examples

const unregisterItem = store.registerItem({ id: "item-1" });
// on cleanup
unregisterItem();

removeValue

(name: StringLike, index: number) => void

Removes a value from an array field.

The array length is preserved: the removed index is replaced with null so indices stay stable for field keys, touched state, errors, and FormRemove focus handling. Filter out null values before submitting if your payload should omit removed items.

Code examples

store.removeValue("tags", 0);
store.removeValue("tags", 1);
// Can also use store.names for type-safety.
store.removeValue(store.names.tags, 0);

renderItem

BivariantCallback<(item: T) => () => void>

Renders an item in the collection. This function returns a cleanup function that unmounts the item.

Code examples

const unrenderItem = store.renderItem({ id: "item-1" });
// on cleanup
unrenderItem();

reset

() => void

Resets the form to its default values.


setError

(name: StringLike, error: SetStateAction<ErrorMessage>) => void

Sets a field error.

Live examples

Code examples

store.setError("name", "Name is required");
store.setError("name", (error) => error + "!");
// Can also use store.names for type-safety.
store.setError(store.names.name, "Name is required");

setErrors

SetState<DeepPartial<DeepMap<T, ErrorMessage>>>

Sets the errors state.

Code examples

store.setErrors({ name: "Name is required" });
store.setErrors((errors) => ({ ...errors, name: "Name is required" }));

setFieldTouched

(name: StringLike, value: SetStateAction<boolean>) => void

Sets a field touched state.

Code examples

store.setFieldTouched("name", true);
store.setFieldTouched("name", (value) => !value);
// Can also use store.names for type-safety.
store.setFieldTouched(store.names.name, true);

setState

<K extends keyof S>(key: K, value: SetStateAction<S[K]>) => void

Sets a state value.


setTouched

SetState<DeepPartial<DeepMap<T, boolean>>>

Sets the touched state.

Code examples

store.setTouched({ name: true });
store.setTouched((touched) => ({ ...touched, name: true }));

setValue

<T>(name: StringLike, value: SetStateAction<T>) => void

Sets a field value.

Live examples

Code examples

store.setValue("name", "John");
store.setValue("name", (value) => value + " Doe");
// Can also use store.names for type-safety.
store.setValue(store.names.name, "John");

setValues

SetState<T>

Sets the values state.

Code examples

store.setValues({ name: "John" });
store.setValues((values) => ({ ...values, name: "John" }));

submit

() => Promise<boolean>

Submits the form. This also triggers validation.

Code examples

if (await form.submit()) {
// Form is submitted.
}

validate

() => Promise<boolean>

Validates the form.

Code examples

if (await store.validate()) {
// Form is valid.
}

useState

UseState<StoreState<T>>

Deprecated: Use useStoreState instead.

Re-renders the component when the state changes and returns the current state.


useSubmit

(callback: FormStoreCallback<FormStoreState<T>>) => void

Deprecated: Use useFormSubmit instead.

Custom hook that accepts a callback that will be used to submit the form when submit is called.

Live examples

Code examples

useFormSubmit(store, async (state) => {
try {
await api.submit(state.values);
} catch (errors) {
store.setErrors(errors);
}
});

useValidate

(callback: FormStoreCallback<FormStoreState<T>>) => void

Deprecated: Use useFormValidate instead.

Custom hook that accepts a callback that will be used to validate the form when validate is called, typically when a form field is touched or when the form is submitted.

Live examples

Code examples

useFormValidate(store, async (state) => {
const errors = await api.validate(state.values);
if (errors) {
store.setErrors(errors);
}
});

useValue

<T = any>(name: StringLike) => T

Deprecated: Use useFormValue instead.

A custom hook that rerenders the component when the value of the given field changes. It accepts a string or a reference to a field name from the names object in the store, for type safety. It returns the value of the field.

Live examples

Code examples

const nameValue = useFormValue(store, "name");
// Can also use store.names for type safety.
const emailValue = useFormValue(store, store.names.email);

Stay tuned

Join 1,000+ subscribers and receive monthly tips & updates on new Ariakit content.

No spam. Unsubscribe anytime. Read latest issue