React Javascript Forms Guide

Nhon Dang
4 min readFeb 18, 2021

Form handling in React is much more different than form handling in vanilla javascript. If you recall, forms in javascript involves attaching an event listener to form, grabbing the values, and sending that information off somewhere (usually a POST/PATCH request). Using forms with React follows a similar convention, but in order to set it up, you’d have to do a bit more work. In today’s blog, I’ll be showing you how to set it up, and how to wire it up to make a POST request.

Typical Workflow

I’ll briefly go over the typical workflow of setting up forms and getting them to work correctly. As I mentioned, there are a bit more steps involved and this blog assumes you have a base understanding of React states and props. States hold information within a class component and props are objects that a parent component passes along to its child component. With this information, we have a few different options or practices to set up forms and their handlers. Regardless, a form will need an onChange listener, an onChange handler, an onSubmit listener, and a submit handler.

Parent to Child Hierarchy

For the examples in this blog, we’ll be building out an application that has a signup component which will hold the form itself. This signup component is a child of “App.js” and we’ll set it up to take in username and password values inputted from a user. Listed below is the App.js file, and everything is pretty run of the mill about it.

App.js File

You can see that the only purpose is to render the navigation bar and sign up form components. In this example, we don’t have a container to hold components, but it won’t be needed.

App.js Rendering Navbar and Signup Form

The Form Itself and Worflow

Now that we know how and where things are being rendered, let’s take a look at the signup form component itself. Take a look below

SignupForm.js

I’ve decided to include state here, rather than the App.js to make everything easier to follow along. Normally you’d put the state and fetch request method in the container and pass it down as a prop, this allows it to be a bit more modular. Let’s break down what this component is responsible for. This component is a class component with a state, it has JSX rendering out the form and on lines 21 and 26 (input tag) contains the “onChange” event listener. Make note of line 16 as it is wired up to an onSubmit event listener. We’re using an anonymous function to pass “e” or the event to handle change methods that we will soon define.

Added the handleChange Methods

These handle change methods will take in all of the user inputs by monitoring any changes in the input fields. Within these change handling methods, we are setting the state to the user inputs so it’ll be easier to make a fetch request within out submit handler. Take a look below.

Submit Handler Method

If you remember from the 3rd picture, line 16 has an onSubmit event listener. Go ahead and scroll up to see that we’ll be using the same workflow of the onChange section. the onSubmit has an anonymous function pointing to a handleSubmit method that takes in the event. Don’t forget the e.preventDefault() method, that much is the same. The fetch itself is the same exact way we do fetches in vanilla javascript as well! We’re setting the state of this component (already and object) to a variable, and simply passing that within the “POST” request. If you’re backend is set up correctly, it should successfully persist to the database.

Closing Notes and Reminders:

The example in this article is a very simple form that is also a class. Without going into hooks, we can declare a state within the form component itself. If this form was a functional component (which it should be), then the state and handleSubmit should be in the parent container. Then you would pass down the state and handleSubmit function as a prop to the form component. Here you would still define the handleChange functions and change the state that was passed down, then call on the handleSubmit prop to send the new state back up to the parent component.

--

--