Topic: React Forms
In React, form submission is handled programmatically using the onSubmit event on a <form> element. Instead of letting the browser reload the page, React lets you intercept the submission, access the form data, and perform actions like validation or API calls — all within your component.
The core steps are: preventing the default browser submission, using controlled components to collect values, and running validation or sending data to a server.
onSubmit handler: a function that runs when the form is submitted.e.preventDefault(): prevents the page from reloading on submit.formData).fetch or axios.A typical React form has:
<form onSubmit={handleSubmit}> wrapper that listens for submit events (clicking the button or pressing Enter).<input /> or <textarea /> that are controlled by state via value and onChange.<button type="submit">Submit</button>.Inside handleSubmit, you almost always call e.preventDefault() to stop the native browser submit behavior and handle everything manually in React.
This example captures a single input value and shows it in an alert without reloading the page.
// Simple controlled form that prevents page reload on submit
import React, { useState } from "react";
function SimpleForm() {
const [name, setName] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
alert(`Form submitted! Hello, ${name}`);
};
return (
<form onSubmit={handleSubmit}>
<h4>Basic Form Submission</h4>
<input
type="text"
className="form-control mb-3"
placeholder="Enter your name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
);
}
export default SimpleForm;
For larger forms, store all values in a single state object and update fields dynamically using the name attribute.
// Registration form storing all input values in a single state object
import React from "react";
function RegistrationForm() {
const [formData, setFormData] = React.useState({
name: "",
email: "",
password: ""
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
console.log("Form Submitted:", formData);
alert(`Welcome ${formData.name}!`);
};
return (
<form onSubmit={handleSubmit}>
<h4>Registration Form</h4>
<input
name="name"
type="text"
className="form-control mb-2"
placeholder="Full Name"
value={formData.name}
onChange={handleChange}
/>
<input
name="email"
type="email"
className="form-control mb-2"
placeholder="Email Address"
value={formData.email}
onChange={handleChange}
/>
<input
name="password"
type="password"
className="form-control mb-3"
placeholder="Password"
value={formData.password}
onChange={handleChange}
/>
<button className="btn btn-success">Register</button>
</form>
);
}
export default RegistrationForm;
This example performs simple client-side validation before showing a success message.
// Login form that validates required fields and email format
import React from "react";
function ValidatedForm() {
const [formData, setFormData] = React.useState({
email: "",
password: ""
});
const [error, setError] = React.useState("");
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
if (!formData.email || !formData.password) {
setError("All fields are required!");
return;
}
if (!formData.email.includes("@")) {
setError("Please enter a valid email address!");
return;
}
setError("");
alert("Login Successful!");
};
return (
<form onSubmit={handleSubmit}>
<h4>Login Form with Validation</h4>
<input
name="email"
type="email"
className="form-control mb-2"
placeholder="Email"
value={formData.email}
onChange={handleChange}
/>
<input
name="password"
type="password"
className="form-control mb-2"
placeholder="Password"
value={formData.password}
onChange={handleChange}
/>
{error && <p className="text-danger">{error}</p>}
<button className="btn btn-primary">Login</button>
</form>
);
}
export default ValidatedForm;
Here, the form sends data to a fake REST API using fetch and shows the JSON response.
// Form that sends user data to an API using fetch and async/await
import React from "react";
function SubmitToAPI() {
const [user, setUser] = React.useState({ name: "", email: "" });
const handleChange = (e) => {
const { name, value } = e.target;
setUser({ ...user, [name]: value });
};
const handleSubmit = async (e) => {
e.preventDefault();
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(user)
});
const data = await response.json();
alert("Submitted Successfully!\n" + JSON.stringify(data, null, 2));
};
return (
<form onSubmit={handleSubmit}>
<h4>Submit Form Data to API</h4>
<input
name="name"
className="form-control mb-2"
placeholder="Name"
value={user.name}
onChange={handleChange}
/>
<input
name="email"
className="form-control mb-2"
placeholder="Email"
value={user.email}
onChange={handleChange}
/>
<button className="btn btn-warning">Submit to API</button>
</form>
);
}
export default SubmitToAPI;
formData. On submit, they are logged to the console and a welcome alert appears.{ name, email } to an API. The response JSON is shown via an alert, proving that the data was submitted.In all cases, e.preventDefault() ensures the app stays on the same page, giving you full control over what happens after submission.
<form> tag so the Enter key triggers submission.e.preventDefault() in onSubmit to avoid page reloads and keep control in React.required attribute for simple, built-in validation.useState with useEffect for real-time validation feedback as the user types.fetch and setTimeout.Goal: Practice how React handles form submissions without reloading the page, validate user data on the client side, and integrate with APIs effectively.