All questions

useForm

Premium

useForm

Forms are deceptively deep: you need current values, per-field errors from validation, which fields have been touched (so you don't show "Required" before the user has even reached the field), and an isSubmitting flag to disable the button during an async submit. useForm is a minimal version of the Formik/React-Hook-Form core — one hook that owns all four and wires up handleChange/handleBlur/handleSubmit.

Implement useForm({ initialValues, validate, onSubmit }). Return { values, errors, touched, isSubmitting, handleChange, handleBlur, handleSubmit, setFieldValue, reset }. Validate on change; on submit, validate everything, mark all fields touched, and only call onSubmit when there are no errors.

Signature

function useForm({ initialValues, validate, onSubmit }) {
  // returns { values, errors, touched, isSubmitting,
  //           handleChange, handleBlur, handleSubmit, setFieldValue, reset }
}

Examples

const f = useForm({
  initialValues: { email: '' },
  validate: (v) => (v.email.includes('@') ? {} : { email: 'Invalid email' }),
  onSubmit: (v) => api.subscribe(v),
});
<form onSubmit={f.handleSubmit}>
  <input name="email" value={f.values.email} onChange={f.handleChange} onBlur={f.handleBlur} />
  {f.touched.email && f.errors.email && <span>{f.errors.email}</span>}
  <button disabled={f.isSubmitting}>Subscribe</button>
</form>

Notes

  • validate(values) returns { field: message } for invalid fields ({} when valid); run it on change and on submit.
  • handleChange reads e.target (checkbox → checked, else value), updates that field, and re-validates.
  • touchedhandleBlur marks a field touched; handleSubmit marks all fields touched (so errors show after a submit attempt).
  • handleSubmitpreventDefault, validate; if there are errors, stop; otherwise set isSubmitting and await onSubmit(values), clearing the flag when done. Keep the handlers stable.
WE’RE LISTENING

Help make UIReady better

Found a bug or have an idea? Tell us about it.

Up to 3 files · 5 MiB each · JPG, PNG, WebP, MP4, WebM, MP3, M4A or WAV