← Back to Chapters

Form Submission in React

? Form Submission in React

Topic: React Forms

? Quick Overview

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.

? Key Concepts

  • Controlled inputs: form fields whose values are stored in React state.
  • onSubmit handler: a function that runs when the form is submitted.
  • e.preventDefault(): prevents the page from reloading on submit.
  • Single source of truth: all form values live in a state object (e.g., formData).
  • Validation: check user input before sending it anywhere.
  • API submission: send data to a backend using fetch or axios.

? Syntax & Theory

A typical React form has:

  • A <form onSubmit={handleSubmit}> wrapper that listens for submit events (clicking the button or pressing Enter).
  • Input fields like <input /> or <textarea /> that are controlled by state via value and onChange.
  • A submit button like <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.

? Code Examples

1️⃣ Basic Form Submission

This example captures a single input value and shows it in an alert without reloading the page.

? View Code Example
// 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;

2️⃣ Handling Multiple Fields

For larger forms, store all values in a single state object and update fields dynamically using the name attribute.

? View Code Example
// 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;

3️⃣ Validation Before Submit

This example performs simple client-side validation before showing a success message.

? View Code Example
// 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;

4️⃣ Submitting Data to an API

Here, the form sends data to a fake REST API using fetch and shows the JSON response.

? View Code Example
// 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;

? Live Output / What Happens When You Run This?

  • SimpleForm: You type your name, click Submit, and an alert pops up greeting you without reloading the page.
  • RegistrationForm: All entered values are stored in formData. On submit, they are logged to the console and a welcome alert appears.
  • ValidatedForm: If any field is empty or the email is invalid, an error message appears. Only valid input triggers the success alert.
  • SubmitToAPI: The form sends { 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.

? Tips & Best Practices

  • Always wrap your inputs inside a semantic <form> tag so the Enter key triggers submission.
  • Use e.preventDefault() in onSubmit to avoid page reloads and keep control in React.
  • Disable the submit button while waiting for server responses to prevent duplicate submissions.
  • Use the HTML required attribute for simple, built-in validation.
  • Combine useState with useEffect for real-time validation feedback as the user types.
  • Show clear success and error messages so users know what happened after they submit.

? Try It Yourself

  1. Create a signup form with fields for username, email, and password.
  2. Show an error message if any field is empty or the email is invalid.
  3. Simulate sending the form data to a fake API endpoint using fetch and setTimeout.
  4. After a successful "submission", display a success message and clear all input fields.

Goal: Practice how React handles form submissions without reloading the page, validate user data on the client side, and integrate with APIs effectively.