Events and forms

Submit a form

Handle the form submit event so keyboard submission and a submit button use one accessible path.

Handle submission on the form, not only on the button. A form can be submitted several ways: clicking the button, pressing Enter in a field, or using assistive technology. The form’s submit event is the one place all of those paths meet, while a click handler on the button catches only one of them.

function TaskForm({ onSave }) {
  const [title, setTitle] = useState('')

  function handleSubmit(event) {
    event.preventDefault()

    const trimmedTitle = title.trim()
    if (!trimmedTitle) return

    onSave(trimmedTitle)
    setTitle('')
  }

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="title">Task title</label>
      <input
        id="title"
        name="title"
        value={title}
        onChange={event => setTitle(event.target.value)}
        required
      />
      <button type="submit">Add task</button>
    </form>
  )
}

The form’s submit event covers pointer clicks and keyboard submission. The button remains a real submit button, so it keeps its native behavior and semantics.

Call preventDefault() because this component handles the result without native navigation. Without it, the browser performs a full page load on submit, and your React state disappears with the page. If the form seems to “flash” and reset, a missing preventDefault() is the first thing to check. For a progressively enhanced server form, you may keep the normal action and method instead and let the browser navigate.

The handler trims the value and returns early when it is empty. React does not validate anything for you; the handler owns that logic. Browser validation such as required improves feedback before submission ever fires. It is not a security boundary. A server endpoint must validate and authorize every request again.

When the save is asynchronous, do not clear the form before it succeeds. Clearing early destroys the user’s input if the request fails. Keep the current value, show a pending state, and display a useful error if the request fails.

Submit once by clicking and once by pressing Enter. Both paths should call the same handler, and you can prove it with a log line in handleSubmit.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →