☰ See All Chapters |
React Handling forms
Using React we can make our forms much more interactive and less static. You add a form with React like any other element:
function DemoComponent(props) { return ( <form> <label>Enter your name: <input type="text" /> </label> </form> ); }
export default DemoComponent; |
There are two main ways of handling forms in React, which differ on a fundamental level: how data is managed.
Uncontrolled form: if the data is handled by the DOM.
Controlled form: if the data is handled by the components
When the data is handled by the components, all the data is stored in the component state. The component state is the single source of truth, rather than the DOM. Some form fields are inherently uncontrolled because of their behavior, like the <input type="file"> field.
Steps to handle forms in function components
Step 1: Use useState Hook to keep track of each inputs value and provide a "single source of truth" for the entire application.
const [userName, setName] = useState("");
Step 2: When an element state changes in a form field managed by a component, we track it using the onChange attribute.
import { useState } from 'react';
function DemoComponent() { const [userName, setUserName] = useState("");
return ( <form> <label>Enter your name: <input type="text" value={userName} onChange={(e) => setUserName(e.target.value)} /> </label> </form> ) } export default DemoComponent; |
Step 3: Use the onSubmit attribute on the form to call the handleSubmit method when the form is submitted:
import { useState } from 'react';
function DemoComponent() { const [userName, setUserName] = useState("");
const handleSubmit = (event) => { event.preventDefault(); alert(`The name you entered was: ${userName}`) }
return ( <form onSubmit={handleSubmit}> <label>Enter your name: <input type="text" value={userName} onChange={(e) => setUserName(e.target.value)} /> </label> <input type="submit" /> </form> ) } export default DemoComponent; |
Steps to handle forms in class components
Step 1: Use state a built-in React object to keep track of each inputs value and provide a "single source of truth" for the entire application.
class Form extends React.Component {
constructor(props) {
super(props)
this.state = { username: '' }
}
}
Step 2: When an element state changes in a form field managed by a component, we track it using the onChange attribute. If component is a class component then In order to set the new state, we must bind this to the onChange attribute method from inside constructor, otherwise this is not accessible from within that method:
import React from 'react';
class DemoComponent extends React.Component { constructor(props) { super(props) this.state = { username: '' } this.handleChange = this.handleChange.bind(this) } handleChange(event) { this.setState({ value: event.target.value }) } render() { return ( <form> <input type="text" value={this.state.username} onChange={this.handleChange} /> </form> ) } } export default DemoComponent; |
Step 3: Use the onSubmit attribute on the form to call the handleSubmit method when the form is submitted:
import React from 'react';
class DemoComponent extends React.Component { constructor(props) { super(props) this.state = { username: '' } this.handleChange = this.handleChange.bind(this) this.handleSubmit = this.handleSubmit.bind(this) } handleChange(event) { this.setState({ value: event.target.value }) } handleSubmit(event) { alert(this.state.username) event.preventDefault() } render() { return ( <form onSubmit={this.handleSubmit}> <input type="text" value={this.state.username} onChange={this.handleChange} /> <input type="submit" value="Submit" /> </form> ) } } export default DemoComponent; |
Handling Validations in form
Validation in a form can be handled in the handleChange method: you have access to the old value of the state, and the new one. You can check the new value and if not valid reject the updated value (and communicate it in some way to the user). HTML Forms are inconsistent. They have a long history, and it shows. React however makes things more consistent for us, and you can get (and update) fields using its value attribute. Here's a textarea and select tag, for example:
<textarea value={this.state.address} onChange={this.handleChange} />
<select value="{this.state.age}" onChange="{this.handleChange}">
<option value="teen">Less than 18</option>
<option value="adult">18+</option>
</select>
All Chapters