React Controlled Components and Forms
Controlling Form Values from State
A controlled form is a form that derives its input values from state
Consider the following form code
import React, { useState } from "react";
function Form() {
const [firstName, setFirstName] = useState("John");
const [lastName, setLastName] = useState("Henry");
return (
<form>
<input type="text" value={firstName} />
<input type="text" value={lastName} />
<button type="submit">Submit</button>
</form>
);
}
export default Form;
Currently, the input values of the form will display what the state of firstName and lastName is set to
- But there is no way to update the state yet.
We can update the state by adding the onChange event listener as follows
<input type="text" onChange={handleFirstNameChange} value={firstName}/>
<input type="text" onChange={handleLastNameChange} value={lastName} />
With this, the onChange will execute every time the value of an input changes
Below, find the functions to handle the changes, you will notice the functions take in an event as an argument, which is passed down from the onChange event listener
function handleFirstNameChange(event) {
setFirstName(event.target.value);
}
function handleLastNameChange(event) {
setLastName(event.target.value);
}
Form Element Types
Form Elements:
<input>, <textarea>, <select>, and <form>
For these, the prop we use is value
For a checkbox <input type="checkbox">, we used checked, which is a true or false value that can be set by the state through an onChange event listener
**A major benefit of controlled forms is how it allows us to use the form values in other components
You could have all the form states, logic, and functions stored in a parent component while passing down this logic as props to the Form component.
As the state updates in the form, you can pass down the state to a different child component for other uses, such as displaying form inputs live as they're being typed.
- This is very useful to capture user input and utilize it throughout your application, even if a server isn't involved.
Form Validation with Controlled Forms
Having controlled forms allows us the functionality to validate the input before setting the State for the input.
For example, if you want the form to allow only numbers between 0 - 5, you can set up an if statement inside the call-back function for the onChange event listener as follows
function handleNumberChange(event) {
const newNumber = parseInt(event.target.value);
if (newNumber >= 0 && newNumber <= 5) {
setNumber(newNumber);
}
}
If the input is invalid, we avoid setting the state and thus preventing the input from updating.
As well, this allows us to set another state variable as an error that can be displayed if the input is not valid
Submitting a Controlled Form
When submitting the form, add an onSubmit event listener to the form element
return ( <form onSubmit={handleSubmit}> //right here <input type="text" onChange={handleFirstNameChange} value={firstName} /> <input type="text" onChange={handleLastNameChange} value={lastName} /> <button type="submit">Submit</button> </form> );
Then create the callback function for handleSubmit as follows
function handleSubmit(event) {
event.preventDefault(); // need to do this like Javascript
const formData = { //Here we are adding the current State data at the
firstName: firstName, //time of submit to an object variable
lastName: lastName,
};
props.sendFormDataSomewhere(formData); //When submitted, this data should go somewhere
setFirstName(""); //This is to clear the current input fields and reset the states
setLastName("");
}
As well, in the handleSubmit call-back function, we can also validate the inputs for submission and send out error messages.
citations:
-Flatiron School