Back to Course

Learn React

0% Complete
0/0 Steps
Lesson 17 of 32
In Progress

Creating and Handling Forms in React

Forms are an essential part of most web applications. They allow users to enter and submit data, and they provide a way for applications to interact with users and gather important information.

In this article, we’ll learn how to create and handle forms in React.

Creating a Form

In React, we create a form by using the form element and adding form controls such as input, select, and textarea.

Here’s an example of a simple form that includes a text input and a submit button:

import React, { useState } from 'react';

function FormExample() {
  const [inputValue, setInputValue] = useState('');

  function handleSubmit(event) {
    event.preventDefault();
    console.log('Form submitted with input value:', inputValue);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Enter some text:
        <input type="text" value={inputValue} onChange={event => setInputValue(event.target.value)} />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}

In this example, we’ve created a form that includes a text input and a submit button. When the form is submitted, the handleSubmit function is called, which logs the input value to the console.

Controlling Form Values with State

In the example above, we used state to store and control the value of the text input. We used the useState hook to create a state variable called inputValue and a function called setInputValue to update the value of inputValue.

We set the value of the text input to the value of inputValue using the value prop, and we added an onChange event handler to the text input that updates the value of inputValue when the input value changes.

By using state to control the value of the form controls, we can easily retrieve and validate the form data when the form is submitted.

Validating Form Data

Validating form data is an important part of handling forms in any application. We can use JavaScript’s built-in form.checkValidity() method to check if a form is valid, and we can use the form.reportValidity() method to display any validation errors to the user.

Here’s an example of how we can validate a form in React:

import React, { useState } from 'react';

function FormExample() {
  const [inputValue, setInputValue] = useState('');
  const [formErrors, setFormErrors] = useState([]);

  function handleSubmit(event) {
    event.preventDefault();

    if (!event.target.checkValidity()) {
      setFormErrors(event.target.validationMessage);
      return;
    }

    console.log('Form submitted with input value:', inputValue);
  }

  return (
    <form onSubmit={handleSubmit} noValidate>
      <label>
        Enter some text:
        <input
          type="text"
          value={inputValue}
          onChange={event => setInputValue(event.target.value)}
          required
        />
      </label>
      {formErrors && <p>{formErrors}</p>}
      <input type="submit" value="Submit" />
    </form>
  );
}

In this example, we’ve added a formErrors state variable and a setFormErrors function to store and update the form errors.

We’ve also added a noValidate prop to the form element to disable the browser’s default form validation. This is important because we want to handle the form validation ourselves using form.checkValidity() and form.reportValidity().

In the handleSubmit function, we check if the form is valid using form.checkValidity(), and if it’s not valid, we set the form errors using setFormErrors.

We’ve also added a conditional rendering to display the form errors if they exist.

Handling Multiple Inputs

In the example above, we only had a single text input. But in most forms, we’ll have multiple inputs such as text inputs, radio buttons, checkboxes, and more.

To handle multiple inputs in a form, we can use the name attribute to group the inputs together and retrieve their values when the form is submitted.

Here’s an example of a form with multiple inputs:

import React, { useState } from 'react';

function FormExample() {
  const [formData, setFormData] = useState({
    firstName: '',
    lastName: '',
    email: '',
    gender: '',
    newsletter: false,
  });

  function handleChange(event) {
    const { name, value, type, checked } = event.target;
    setFormData(prevFormData => ({
      ...prevFormData,
      [name]: type === 'checkbox' ? checked : value,
    }));
  }

  function handleSubmit(event) {
    event.preventDefault();
    console.log('Form submitted with data:', formData);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        First Name:
        <input
          type="text"
          name="firstName"
          value={formData.firstName}
          onChange={handleChange}
        />
      </label>
      <br />
      <label>
        Last Name:
        <input
          type="text"
          name="lastName"
          value={formData.lastName}
          onChange={handleChange}
        />
      </label>
      <br />
      <label>
        Email:
        <input
          type="email"
          name="email"
          value={formData.email}
          onChange={handleChange}
        />
      </label>
      <br />
      <label>
        Gender:
        <input
          type="radio"
          name="gender"
          value="male"
          checked={formData.gender === 'male'}
          onChange={handleChange}
        />
        Male
        <input
          type="radio"
          name="gender"
          value="female"
          checked={formData.gender === 'female'}
          onChange={handleChange}
        />
        Female
      </label>
      <br />
      <label>
        Subscribe to newsletter:
        <input
          type="checkbox"
          name="newsletter"
          checked={formData.newsletter}
          onChange={handleChange}
        />
      </label>
      <br />
      <input type="submit" value="Submit" />
    </form>
  );
}

In this example, we’ve added a formData state variable and a setFormData function to store and update the form data.

We’ve also added a handleChange function that updates the form data when any of the form inputs are changed.

In the handleChange function, we use destructuring to get the name, value, type, and checked properties of the input element. We then use the setFormData function to update the form data with the new input value.

For checkboxes and radio buttons, we need to use the type and checked properties to determine the value of the input. For all other input types, we can use the value property.

We’ve also added a handleSubmit function that is called when the form is submitted. This function prevents the default form submission behavior and logs the form data to the console.

Finally, we’ve added an onSubmit event handler to the form element and set it to the handleSubmit function. This ensures that the handleSubmit function is called when the form is submitted.

In this way, we can handle multiple inputs in a form and retrieve their values when the form is submitted.

Exercises

To review these concepts, we will go through a series of exercises designed to test your understanding and apply what you have learned.

Create a form with the following inputs:
-A text input for the user’s name
-A dropdown menu with options for the user’s favorite color
-A group of radio buttons for the user’s gender
-A checkbox for whether the user wants to receive a newsletter
Use the name attribute to group the inputs together and retrieve their values when the form is submitted.

import React, { useState } from 'react';

function FormExample() {
  const [formData, setFormData] = useState({
    name: '',
    favoriteColor: '',
    gender: '',
    newsletter: false,
  });

  function handleChange(event) {
    const { name, value, type, checked } = event.target;
    setFormData(prevFormData => ({
      ...prevFormData,
      [name]: type === 'checkbox' ? checked : value,
    }));
  }

  function handleSubmit(event) {
    event.preventDefault();
    console.log('Form submitted with data:', formData);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input
          type="text"
          name="name"
          value={formData.name}
          onChange={handleChange}
        />
      </label>
      <br />
      <label>
        Favorite Color:
        <select name="favoriteColor" value={formData.favoriteColor} onChange={handleChange}>
          <option value="red">Red</option>
          <option value="green">Green</option>
          <option value="blue">Blue</option>
        </select>
      </label>
      <br />
      <label>
        Gender:
        <input
          type="radio"
          name="gender"
          value="male"
          checked={formData.gender === 'male'}
          onChange={handleChange}
        />
        Male
        <input
          type="radio"
          name="gender"
          value="female"
          checked={formData.gender === 'female'}
          onChange={handleChange}
        />
        Female
      </label>
      <br />
      <label>
        Subscribe to newsletter:
        <input
          type="checkbox"
          name="newsletter"
          checked={formData.newsletter}
          onChange={handleChange}
        />
      </label>
      <br />
      <input type="submit" value="Submit" />
    </form>
  );
}

Write a list of 5 reasons why it is important to validate form data.

  1. To prevent malicious attacks such as SQL injection or cross-site scripting (XSS).
  2. To ensure that the data entered by the user is in the correct format and meets the requirements of the application.
  3. To improve the user experience by providing clear error messages and preventing the submission of invalid data.
  4. To improve the accuracy and reliability of the data being collected.
  5. To reduce the workload of manual data validation by the server or database.

What is the purpose of the event.preventDefault() method in a form submission event handler?

The event.preventDefault() method is used to prevent the default form submission behavior, which is typically to send the form data to the server as a request. By calling preventDefault(), we can instead handle the form submission in JavaScript and perform any necessary actions before the form data is sent to the server.

What is the name attribute used for in a form input element, and why is it important?

The name attribute is used to identify the input element and group it with other related input elements. When the form is submitted, the input elements are sent to the server as a set of name-value pairs. The name attribute specifies the name of the input element, and the value attribute specifies the value entered by the user.

The name attribute is important because it allows us to easily retrieve and process the form data on the server or in JavaScript. It also helps to ensure that the input elements are properly grouped and associated with each other.

Give 3 examples of form controls.

input, select, and textarea