Common Events: `onSubmit` (Part 3) #44
📖 Introduction
We've learned how to handle clicks with onClick
and user input with onChange
. The final piece of the puzzle for creating interactive forms is handling the submission itself. This is done with the onSubmit
event handler.
This article will teach you how to properly handle form submissions in React. We'll cover how to attach the onSubmit
event to a <form>
element and, most importantly, how to prevent the default browser behavior to handle the submission with JavaScript.
📚 Prerequisites
Before we begin, please ensure you have a solid grasp of the following concepts:
- Controlled Components: You must be comfortable using
onChange
anduseState
to manage the state of form inputs. - React Event Handlers: You should know how to define and pass event handlers like
onClick
. - The
SyntheticEvent
Object: Understanding that the event handler receives an event objecte
and whate.preventDefault()
does.
🎯 Article Outline: What You'll Master
In this article, you will learn:
- ✅ The
onSubmit
Event: How to use theonSubmit
handler to capture form submission events. - ✅ Preventing Default Behavior: Why
e.preventDefault()
is essential for handling form submissions in a single-page application. - ✅ Putting It All Together: Building a complete, controlled form that manages input state and handles submission.
- ✅ Where to Attach
onSubmit
: Understanding whyonSubmit
belongs on the<form>
tag, not the<button>
.
🧠 Section 1: The Core Concept: Capturing the Submit Event
In standard HTML, when you click a <button type="submit">
inside a <form>
, the browser triggers a submit
event. The default browser action for this event is to serialize the form's data and send it to the URL specified in the form's action
attribute, causing a full page reload.
In a React single-page application (SPA), we almost never want this default behavior. We want to intercept the submission, handle the data with JavaScript (e.g., send it to an API), and update our UI without a page refresh.
The onSubmit
event handler, attached to the <form>
element, is how we do this.
💻 Section 2: Building a Complete Login Form
Let's build a simple login form that demonstrates how onChange
and onSubmit
work together.
// code-block-1.jsx
import React, { useState } from 'react';
export default function LoginForm() {
// 1. State for each input
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
// 2. The submission handler
function handleSubmit(event) {
// 3. Prevent the default form submission behavior
event.preventDefault();
// 4. Handle the form data
alert(`Logging in with Username: ${username} and Password: ${password}`);
// In a real app, you'd likely send this data to a server here
// and then clear the form.
}
return (
// 5. Attach the handler to the form's onSubmit event
<form onSubmit={handleSubmit}>
<div>
<label>Username: </label>
<input
type="text"
value={username}
onChange={e => setUsername(e.target.value)}
/>
</div>
<div>
<label>Password: </label>
<input
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
/>
</div>
{/* 6. A button with type="submit" will trigger the form's onSubmit */}
<button type="submit">Log In</button>
</form>
);
}
Step-by-Step Code Breakdown:
useState
for Inputs: We have two state variables,username
andpassword
, to control our two inputs. Each has its ownonChange
handler to keep the state in sync.function handleSubmit(event)
: This is our submission handler. It will be called when the form is submitted.event.preventDefault()
: This is the most critical line. It tells the browser, "Do not perform your default action of reloading the page. I will handle this event with JavaScript."- Handling Data: Inside the handler, we have access to the latest
username
andpassword
values from our state. Here, we just show an alert, but in a real application, this is where you would make an API call. <form onSubmit={handleSubmit}>
: We attach our handler to theonSubmit
prop of the<form>
element.<button type="submit">
: A button withtype="submit"
inside a form will automatically trigger the form'sonSubmit
event when clicked. Pressing "Enter" in a text field will also trigger it.
🛠️ Section 3: A Common Pitfall: onClick
vs. onSubmit
A common mistake is to put the submission logic in an onClick
handler on the submit button.
Incorrect:
// ANTI-PATTERN: Don't do this!
<form>
{/* ... inputs ... */}
<button type="submit" onClick={handleSubmit}>Log In</button>
</form>
Why is this bad?
- It's not accessible. This breaks the default browser behavior of allowing users to submit a form by pressing the "Enter" key in an input field. The
onSubmit
event on the<form>
tag handles both button clicks and "Enter" key presses automatically. - It's semantically incorrect. The submission event belongs to the form as a whole, not just the button.
Always attach your submission handler to the <form>
element's onSubmit
prop.
💡 Conclusion & Key Takeaways
You've now learned how to handle the complete lifecycle of a form in React, from managing input changes with onChange
to handling the final submission with onSubmit
. This is a fundamental skill for building any interactive React application.
Let's summarize the key takeaways:
onSubmit
Belongs on the<form>
: TheonSubmit
event handler should always be placed on the<form>
element, not on the submit button.- Always Call
e.preventDefault()
: In youronSubmit
handler, your first line should almost always bee.preventDefault()
to stop the browser from reloading the page. - State is the Source of Truth: In a controlled form, the component's state holds the form data. Your
onSubmit
handler reads from this state to get the final values. type="submit"
Triggers the Event: A<button>
withtype="submit"
(or pressing Enter in an input) will trigger the parent form'sonSubmit
event.
Challenge Yourself:
Create a ContactForm
component with fields for name
and email
. Manage their state with useState
. When the form is submitted, prevent the default behavior and log an object containing the name and email to the console (e.g., console.log({ name, email })
).
➡️ Next Steps
You now have a solid understanding of how to handle the most common user events in React. In the next article, "Passing Event Handlers as Props", we will explore how to create reusable components (like a generic Button
) by passing event handlers down from parent components.
Thank you for your dedication. Stay curious, and happy coding!
glossary
onSubmit
: A React event handler that is triggered when a<form>
is submitted, either by clicking a button withtype="submit"
or by pressing Enter in an input field.e.preventDefault()
: A method on the event object that tells the browser not to perform its default action for that event. For a form submission, this prevents a page reload.