Introduction to Managing the Form State
Learn how to create a React form with controlled components and manage the values of the form fields in the component's state.
We'll cover the following
Setup
This course allows you to code along so that it’s easier to get a good grasp of the concepts you’ll be learning. You can code directly in this browser by editing and running the code widgets on this platform.
Create the form interface
Let’s create the markup for our form and give it some CSS styles.
import React from 'react'; import './style.css'; import ReactDOM from 'react-dom'; import App from './app.js'; ReactDOM.render( <App />, document.getElementById('root') );
The code snippet above is the markup and style for a form’s interface. We won’t need to go into details.
Currently, the fields in this form are uncontrolled components because they manage their own states, and no field is aware of the state of another field. So to get the input data from any of the fields, we need to create event listeners. However, we won’t be doing that in this lesson.
Next, we’ll create component-level states that the input fields will get their data from.
Manage the form state
We make use of the useState
hook to manage the state in React functional components. The syntax is as follows:
const [name, setName] = useState("");
This creates a state variable, name
, which is accessible throughout the component, and a setName
function that can be used to update the value of name
. The setName
function is also accessible throughout the component.
Let’s update our app.js file.
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; }
From line 4 to line 9, we create a state to manage the values of our input fields. The values
object contains four keys: name
, email
, phone
, and password
. We also have a setValues
function that we’ll use to update any or all of the keys in values
.
From line 11 to line 16, we create a handleChange
function. This function uses the setValues
function to update the value of the values
object in the state.
Let’s take a closer look at the content of the function.
const handleChange = (e) => {setValues({...values,[e.target.name]: e.target.value,});};
This expression updates the value of event.target.name
(the name of the field that was changed) to e.target.value
(the current value of the field).
For each input field, we make them get their values from the state, and we indicate an onChange
event that calls the handleChange
function. This means that whenever the value of an input field is changed, it calls the handleChange
function with an argument event
, which is the onChange
event. The handleChange
function uses this event
object to know which field has called it. It then gets the name
of the field that we have specified and updates its value in the state with the field’s value after the change.
Note: We use the names of these input fields as the keys of our
values
state. This makes it easier to track.
From line 66 to line 79, we write markup that displays the values of values.name
, values.email
, values.phone
, and values.password
.
When we type into any of the input fields, we see that whatever we type gets displayed in the corresponding section where the values of our state for that field are displayed.
This shows us a number of things.
- The values of a component state can be accessed from anywhere in the component.
- When we allow our form to get its data from the component-level state, we have access to whatever is inputted into the form as soon as it gets inputted. This opens many possibilities, which are listed below:
- Our forms are immediately validated.
- Our form fields must perform actions based on the input of another field. A common example is when we have two select drop-downs in a form. The first drop-down enables us to select a country, and the second allows us to select a region in the selected country. The drop-down that displays the list of regions must include a selected country, so it provides the possible regions from that country.
Summary
Let’s highlight the steps we took to create a controlled form component, which has its data managed in the component’s state.
- We created the interface for our form.
- We created an object in the state using the
useState
hook. This gave us access to an identifier we used to get the value of the state and a function to modify the state. - We created a
handleChange
event that used the state-modifying function to update the value of a key in a state. - We allow all input fields to get their values from the state.
- We listened to the
onChange
event of each input field and called thishandleChange
function when the event was fired so it updates the state with the new input value.
Since we have access to the form data at all times, this can help us validate the values provided in the form before sending our data to the API or other components.