Forms

Uncontrolled Forms

In an uncontrolled form, we let the browser handle the form's state and rendering. We only react when the form is submitted using an onSubmit event handler.

  1. Set up the HTML form as usual with the appropriate attributes (name, value, etc.).

  2. Add an onSubmit event handler.

  3. Use FormData to get the form values.

const UncontrolledForm = () => {
  const handleSubmit = (event) => {
    event.preventDefault();
    const formData = new FormData(event.target);
    const fields = Object.fromEntries(formData);
    console.log(fields);
    // axios.post("/", fields);
  };

  return (
    <form onSubmit={handleSubmit}>
      <h1>Uncontrolled Form</h1>
      <input type="text" name="name" placeholder="Name" />
      <input type="email" name="email" placeholder="Email" />
      <textarea name="comment" placeholder="Comment"></textarea>
      <input type="submit" />
    </form>
  );
};

Controlled Forms

In a controlled form, we wire up React to handle the form fields' states and rendering. This is typically used for cases where we need live access to the form values as the user enters data such as live form validation.

Controlled forms require a bit more setup than uncontrolled forms because state will be updated every time a form field changes (through keystrokes, clicks, etc.).

  1. Create a state object with each form field's name as a property.

  2. Add an onChange on each form field that will update the state with its new value.

  3. Add a value prop to each form field and assign the corresponding state value.

  4. Add an onSubmit event on the form and use the state object to get the form values.

const ControlledForm = () => {
  const [fields, setFields] = useState({
    name: "",
    email: "",
  });

  const handleChange = (event) => {
    const { name, value } = event.target;
    setFields({
      ...fields,
      [name]: value,
    });
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    console.log(fields);
    // axios.post("/", fields);
  };

  return (
    <form onSubmit={handleSubmit}>
      <h1>Controlled Form</h1>
      <input
        type="text"
        name="name"
        placeholder="Name"
        value={fields.name}
        onChange={handleChange}
      />
      <input
        type="email"
        name="email"
        placeholder="Email"
        value={fields.email}
        onChange={handleChange}
      />
      <input type="submit" />
    </form>
  );
};

Live Password Confirmation Validation

import { useState } from "react";

const Form = () => {
  const [fields, setFields] = useState({
    username: "",
    password: "",
    confirmPassword: "",
  });
  const [passwordMatch, setPasswordMatch] = useState(
    fields.password === fields.confirmPassword
  );

  const handleChange = (event) => {
    const { name, value } = event.target;

    if (name === "confirmPassword") {
      setPasswordMatch(value === fields.password);
    }

    setFields({
      ...fields,
      [name]: value,
    });
  };

  return (
    <form>
      <input
        type="text"
        name="username"
        value={fields.username}
        onChange={handleChange}
        placeholder="Username"
      />
      <input
        type="password"
        name="password"
        value={fields.password}
        onChange={handleChange}
        placeholder="Password"
      />
      <input
        type="password"
        name="confirmPassword"
        value={fields.confirmPassword}
        onChange={handleChange}
        placeholder="Confirm Password"
      />
      {!passwordMatch && <p>Passwords don't match</p>}
    </form>
  );
};

Last updated