useFormState
Manages named form values, validation, touched state, and submission.
About
useFormState coordinates a record of controlled form values, field errors, touched flags, and synchronous or asynchronous submission.
Example
import { useState } from "react";
import { useFormState } from "rooks";
type SignupFields = {
email: string;
updates: boolean;
};
export default function SignupForm() {
const [message, setMessage] = useState("");
const form = useFormState<SignupFields>({
initialValues: { email: "", updates: false },
validate: (name, value) => {
if (name === "email" && !String(value).includes("@")) {
return "Enter a valid email address";
}
return undefined;
},
onSubmit: (values) => {
setMessage(values.updates ? "Subscribed with updates" : "Subscribed");
},
});
return (
<form onSubmit={form.handleSubmit}>
<label>
Email
<input
name="email"
value={form.values.email}
onChange={form.handleChange}
/>
</label>
{form.touched.email && form.errors.email && (
<p role="alert">{form.errors.email}</p>
)}
<label>
<input
name="updates"
type="checkbox"
checked={form.values.updates}
onChange={form.handleChange}
/>
Product updates
</label>
<button type="submit" disabled={form.isSubmitting}>
Submit
</button>
<p>{message}</p>
</form>
);
}Parameters
Pass an object with:
initialValues: required record that defines the field keys and starting values.validate(name, value, values): optional function returning an error string orundefined.onSubmit(values): optional function returningvoid | Promise<void>.
The source module declares option, result, and validator types, but the rooks entrypoint does not re-export them. Use inference or local shapes rather than importing those names.
Return value
The result contains values, errors, touched, isSubmitting, isValid, handleChange, handleSubmit, setFieldValue, setFieldError, setFieldTouched, and reset. handleChange supports input, textarea, and select change events. handleSubmit accepts a form submit event and returns void.
Behavior and lifecycle
handleChange uses checked for checkboxes and string value for every other control, marks the field touched, and validates it. The validator receives the next field value but the full values record from the previous render. Programmatic field setters do not automatically validate or mark fields touched. Submit prevents the default action, marks every current key touched, validates all fields, and calls onSubmit only when valid. isValid means the current error object has no keys.
A valid submission sets isSubmitting until the returned promise settles. Rejections and synchronous errors are not caught, and repeated submits are not blocked automatically. reset restores the latest initialValues captured by the hook and clears errors, touched flags, and submission state.
Compatibility and accessibility
The hook uses React state only and is safe during server rendering. It does not render labels, connect errors with aria-describedby, focus the first invalid field, parse numeric values, or disable duplicate submissions. The form must provide those behaviors.
Related
- useInput manages one controlled input.
- useCheckboxInputState manages one checkbox.