Introduction to React Forms

Find out what forms are, their importance to web applications, the standard life-cycle of forms, and how they are created with React.

What are forms?

Forms are one of the most vital pieces of a web application. They are what makes a web application interactive. Users interact with applications through forms by providing necessary data that the server processes. The server then computes the data and sends feedback to the user. This is a classic illustration of how a computer functions. A computer accepts data, processes the data, and supplies the result of the data. In web applications, this Input -> Process -> Output flow is empowered by forms. Some situations in which forms are used include:

  • Logging in
  • Searching for content
  • Placing an order online

We can use forms anywhere we need to get data from our users.

While developing forms for a web application, it’s important to make sure that those forms are usable and interactive. While filling out the form, users need to know when they are getting it wrong. They need to know how to make it right. They also need to be aware of the status of the form submission after submitting the form.

Let’s see how a standard form should work on the client side.

Press + to interact
A standard form flow
A standard form flow

Classic form building

One way to create forms is to allow the form to directly submit its data to the server. The server then processes this data and responds by sending a new webpage to the client. This way, after receiving the response from the server, the client redirects to the new webpage from the server.

This is a classic example:

Press + to interact
<form action="/register.php" method="post">
<label for="name">Name</label>
<input type="text" id="name" name="name" />
<label for="email">Email</label>
<input type="email" id="email" name="email" />
<button type="submit">Register</button>
</form>

Here, after the user clicks on the “Submit” button, the form submits itself to the server without us having to handle any of the data. The server then processes the data and responds with a new webpage or an error message.

Creating React forms

The classic method of form creation will not work with single-page applications (SPAs)A single-page application (SPA) is a web application that loads a single page. The content of this page is updated via interactions with the user and by using JavaScript APIs (like the Fetch API) to interact with the server. An example of a SPA is a React application. like React apps. This is because SPAs load just one page. Because the server is made to respond with a web page that the client will redirect to, the app is no longer a SPA.

So with SPAs like React applications, we have to collect all the form data on the client side, validate them if necessary, then either process the data and update the interface with information based on the form data or send the data to the server via a JavaScript API like the Fetch API. The server will process this request and send us some data, which we’ll use to update our client. This process will make our forms more user-friendly and interactive. This is because we are getting the data that our users input.

We can validate this data and give the users immediate feedback when there is an error. This is better than having to wait for our form to make the trip to the server and back before our users are notified of an error.

Here’s the issue with this flow, especially with React applications—this process could easily become repetitive, verbose, and difficult to manage as the form becomes more complex. Think about having to collect data from multiple form fields, validating and displaying errors for each of the fields when there is invalid input. We’ll be doing this and giving each field access to the current state of the form—disabled, error, and submitting states.

In the next two sections, we'll see how to develop a basic React form the most common way. The form will be basic, and we might not encounter any difficulty working on it. But we'll analyze it to see how easily the difficulty could escalate as the form gets more complex. In the section after that, we'll look at a better solution, a way to build forms in React without any frustration involved.

Before we go ahead, let's see what types of forms we can build with React.

Types of React forms

Recall that our goal is to create forms that give us access to the data our users input in the form. This makes it possible for us to validate the form and perform other actions based on the data from the form.

In React, there are two ways we can write our forms, and both ways give us access to the form data:

  • Uncontrolled components
  • Controlled components

Uncontrolled components

A React form with uncontrolled components is similar to a classic HTML form in which each HTML element controls its state.

Ordinarily, with plain JavaScript, we need to write event listeners to listen to changes in these HTML elements and get their current input data. But with uncontrolled components in React, we won’t use event listeners. Instead, we can use a ref to get the value from each element.

Note: In React, refs allow us to store a reference to DOM nodes or React elements. This way, we can grab the internal state of the node or element.

We’ll see an example of this type of form in another lesson.

Controlled components

A form with controlled components is what the React team recommends and we’ll see why.

In React, there’s the concept of state management. This allows React components to maintain their state. If we allow form elements to manage their state, there will be multiple sources of truth in a single component. Controlled components, therefore, provide a way for the components to control the state of form elements. This introduces a single source of truth.

There are a number of advantages that controlled components have over uncontrolled components:

  • It’s easier to manage a form because we’re tracking a single source of truth.

  • It’s easier for form elements to share states in real-time without listening to events—for example, keeping a button disabled until all fields are filled.

  • We can control how we want our users’ data to be displayed.