In this tutorial, we will be learning how to handle forms and user input in a React application. By the end of this tutorial, you will have a clear understanding of how to create forms, capture user input, and manage form state in React.
You will learn:
Prerequisites:
In React, form data is usually handled by the components. When the state changes, the component re-renders.
Controlled Components in React:
In HTML, form elements like <input>
, <textarea>
, and <select>
typically maintain their own state and update it based on user input. In React, mutable state is typically kept in the state property of components, and only updated with setState()
.
Here is a simple example of a form with a single input.
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<NameForm />,
document.getElementById('root')
);
In this code, the NameForm
component has a state with a value
property. This value is updated every time the user types in the input field thanks to the handleChange
method. When the form is submitted, the handleSubmit
method is triggered, showing an alert with the inputted name.
In this tutorial, we've learned how to create a form in React, capture user input, and manage the form's state. We've seen that in React, the form's state is typically kept in the component's state property and only updated with setState()
.
Exercise 1: Create a form with two input fields: "First Name" and "Last Name". Show an alert with the inputted names when the form is submitted.
Solution:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {
firstName: '',
lastName: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
handleSubmit(event) {
alert('Name was submitted: ' + this.state.firstName + ' ' + this.state.lastName);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
First Name:
<input type="text" name="firstName" value={this.state.firstName} onChange={this.handleChange} />
</label>
<label>
Last Name:
<input type="text" name="lastName" value={this.state.lastName} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<NameForm />,
document.getElementById('root')
);
In this code, we have two input fields, each with its own value in the state. The handleChange
method is updated to handle the change of any input field, thanks to the dynamic key [event.target.name]
.
Exercise 2: Expand the previous form by adding a "Favorite Color" dropdown field with options "Red", "Green", "Blue". Show an alert with the inputted names and selected color when the form is submitted.
Solution:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {
firstName: '',
lastName: '',
favoriteColor: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
handleSubmit(event) {
alert('Name was submitted: ' + this.state.firstName + ' ' + this.state.lastName + ', Favorite color: ' + this.state.favoriteColor);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
First Name:
<input type="text" name="firstName" value={this.state.firstName} onChange={this.handleChange} />
</label>
<label>
Last Name:
<input type="text" name="lastName" value={this.state.lastName} onChange={this.handleChange} />
</label>
<label>
Favorite Color:
<select name="favoriteColor" value={this.state.favoriteColor} onChange={this.handleChange}>
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<NameForm />,
document.getElementById('root')
);
In this code, we added a dropdown field for "Favorite Color". The handleChange
method works for this field as well, showing the flexibility of this approach.
Tips for further practice: Try adding more fields to the form, such as a checkbox or a radio button group. Experiment with different form validation rules and feedback messages for the user.