Skip to content

Forms in React

Forms are central to most web apps — login, checkout, settings, search. React forms combine JSX inputs with state or refs and submit handlers. This lesson introduces form structure before diving into controlled and uncontrolled patterns.

Form Elements in JSX

React supports standard HTML form elements: <input>, <textarea>, <select>, <checkbox>, and <button>. Use htmlFor on labels and associate inputs with accessible names.

Handle submission with onSubmit on the <form> element rather than onClick on the submit button — this supports Enter key submission and screen readers correctly.

function ContactForm() {
  const handleSubmit = (e) => {
    e.preventDefault();
    const form = new FormData(e.currentTarget);
    console.log(Object.fromEntries(form));
  };

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="email">Email</label>
      <input id="email" name="email" type="email" required />
      <button type="submit">Send</button>
    </form>
  );
}

FormData reads values from named inputs — useful for uncontrolled forms.

Form Building Blocks

<form onSubmit={handleSubmit}>
  <label htmlFor="name">Name</label>
  <input id="name" name="name" />

  <select name="country">...</select>

  <textarea name="message" />

  <button type="submit">Submit</button>
</form>
  • Always prevent default on submit in SPAs.
  • Use name attributes for FormData and native serialization.
  • Group related fields with <fieldset> and <legend> for accessibility.
  • Choose controlled or uncontrolled strategy consistently per form.

Form Elements Reference

Common form inputs and their React considerations.

Element Value prop Change event
<input type="text"> value onChange
<checkbox> checked onChange
<select> value onChange
<textarea> value (not children) onChange
<input type="file"> uncontrolled typically onChange
<button type="submit"> N/A triggers form submit

Form Libraries

For complex validation and many fields, libraries like React Hook Form, Formik, or TanStack Form reduce boilerplate. They work with both controlled and uncontrolled inputs and integrate well with Zod for schema validation.

  • React Hook Form — minimal re-renders, popular in 2024+.
  • Formik — mature, explicit field-level state.
  • TanStack Form — framework-agnostic, type-safe.
  • Start plain; adopt a library when complexity justifies it.

Accessible Forms

Associate labels with inputs, indicate required fields, surface validation errors with aria-invalid and aria-describedby, and ensure keyboard users can complete every field.

Common Mistakes

  • Using onClick on submit buttons instead of onSubmit on forms.
  • Mixing controlled and uncontrolled inputs on the same field.
  • Putting text content inside <textarea> when using controlled value.
  • Forgetting name attributes when using FormData.

Key Takeaways

  • Handle form submission with onSubmit and preventDefault.
  • Use semantic labels and accessible error messaging.
  • Choose controlled or uncontrolled patterns deliberately.
  • Consider form libraries for complex multi-step forms.

Pro Tip

Prototype forms with plain React first. You'll understand what form libraries automate and when you actually need them.