Forms In React

In this article, we will be discussing more about forms in React and different ways to create and handle forms in React. So let's grab a cup of coffee and start coding!
 
Forms are the most important part of any application. It is a way for the user to interact with the application. We have forms for implementing Login/Register functionality, for adding or updating data into the application, etc. Forms play an important role in the application. For creating forms in HTML we have an element called <form>. Simple HTML forms look like,
  1. <form>  
  2.   <label for="name">Name:</label><br>  
  3.   <input type="text" id="name" name="name" value="John"><br>  
  4.   <input type="submit" value="Submit">  
  5. </form>  
Some of the common use cases of forms are,
  •  Login and Registration Forms
  • Contact Form
  • Checkout Forms
  • Create/Edit Order Forms
  • etc. 
In this article, we will be discussing different ways to create forms in React.
 
Let's get started.
 
TL;DR

Different ways to create Forms in React

 
React has two types of components; i.e. Controlled Components and Uncontrolled Components. So with the help of these types, we can create forms in two different ways:
  • Forms using Controlled Components
  • Forms using Uncontrolled Components

Forms using Controlled Components

 
We know that HTML elements like input remember what we type. So, in the same way, we can use react component state to store data of these form elements. So when data of forms elements is handled by react component then it is called a Controlled Component. In the controlled component, the only source of truth is a component state, not a DOM element.
 
In this article, we will implement the form with the help of Controlled Components. So we will be using some of the HTML elements like input, radio buttons, select dropdown.
We will implement flow for a single input element and then we will add remaining elements. Create a component which has a form tag and has one input element. So it looks like as below,
  1. import React, { Component } from "react";  
  2.   
  3. class ControlledFormComponent extends Component {  
  4.   render() {  
  5.     return (  
  6.       <div>  
  7.         <h3>Controlled Component</h3>  
  8.         <br />  
  9.         <form>  
  10.           <label>Student Name: </label>  
  11.           <input type="text" placeholder="enter student name" />  
  12.         </form>  
  13.       </div>  
  14.     );  
  15.   }  
  16. }  
  17.   
  18. export default ControlledFormComponent;  
It looks something like,
As this is a controlled component, the state of a component is going to handle the form data. So let's create a state in component and add on a change event on the input element to change the state of a component when the value of input element is changed. To see what's in state object print the state in the  bottom of the form.
  1. import React, { Component } from "react";  
  2.   
  3. class ControlledFormComponent extends Component {  
  4.   
  5.   constructor(props) {  
  6.     super(props);  
  7.     this.state = {  
  8.       studentName: ""  
  9.     };  
  10.     this.onNameChangeHandler = this.onNameChangeHandler.bind(this);  
  11.   }  
  12.   
  13.   onNameChangeHandler(e){  
  14.     this.setState({  
  15.       studentName: e.target.value  
  16.     })  
  17.   }  
  18.   
  19.   render() {  
  20.     return (  
  21.       <div>  
  22.         <h3>Controlled Component</h3>  
  23.         <br />  
  24.         <form>  
  25.           <label>Student Name: </label>  
  26.           <input   
  27.               type="text"   
  28.               placeholder="enter student name"  
  29.               onChange={this.onNameChangeHandler} />  
  30.         </form>   
  31.         <hr/>  
  32.         <p>State of Component</p>        
  33.           <pre>{JSON.stringify(this.state, null, 2) }</pre>       
  34.       </div>  
  35.     );  
  36.   }  
  37. }  
  38.   
  39. export default ControlledFormComponent;  
So we have created a state and added studentName as property. After that, we have created onChange handler which will change the state and bind it to onChange event of the input element and we also printed the state object to see the changes in component state.
 
In the same way, we can add another HTML element and bind it to a state of the component.
 
So we will add the radio button and select in our student form. First, add two new properties in the state for holding data of our new elements; i.e gender and state.
  1. <label>Gender: </label>  
  2.           <label>Male</label>  
  3.           <input  
  4.             type="radio"  
  5.             name="gender"  
  6.             value="male"  
  7.             checked={this.state.gender === "male"}  
  8.             onChange={this.onChangeHandler}  
  9.           />  
  10.           <label>Female</label>  
  11.           <input  
  12.             type="radio"  
  13.             name="gender"  
  14.             value="female"  
  15.             checked={this.state.gender === "female"}  
  16.             onChange={this.onChangeHandler}  
  17.           />  
  18.           <br />  
  19.           <br />  
  20.           <label>State: </label>  
  21.           <select  
  22.             name="state"  
  23.             value={this.state.state}  
  24.             onChange={this.onChangeHandler}  
  25.           >  
  26.             <option value="Maharashtra">Maharashtra</option>  
  27.             <option value="Madhya Pradesh">Madhya Pradesh</option>  
  28.             <option value="Karnataka">Karnataka</option>  
  29.             <option value="West Bengal">West Bengal</option>  
  30.           </select>  
Adding the separate change event handler function for HTML element is not the correct approach. We will add only one handler function to handle all our HTML element change events. 
  1. onChangeHandler(e){  
  2.     this.setState({  
  3.       [e.target.name]: e.target.value  
  4.     })  
  5.   }  
So the final component looks like below,
  1. import React, { Component } from "react";  
  2.   
  3. class ControlledFormComponent extends Component {  
  4.   constructor(props) {  
  5.     super(props);  
  6.     this.state = {  
  7.       studentName: "",  
  8.       gender: "",  
  9.       state: "Maharashtra"  
  10.     };  
  11.     this.onChangeHandler = this.onChangeHandler.bind(this);  
  12.   }  
  13.   onChangeHandler(e) {  
  14.     this.setState({  
  15.       [e.target.name]: e.target.value  
  16.     });  
  17.   }  
  18.   render() {  
  19.     return (  
  20.       <div>  
  21.         <h3>Controlled Component</h3>  
  22.         <br />  
  23.         <form>  
  24.           <label>Student Name: </label>  
  25.           <input  
  26.             type="text"  
  27.             name="studentName"  
  28.             placeholder="enter student name"  
  29.             onChange={this.onChangeHandler}  
  30.           />  
  31.           <br />  
  32.           <br />  
  33.           <label>Gender: </label>  
  34.           <label>Male</label>  
  35.           <input  
  36.             type="radio"  
  37.             name="gender"  
  38.             value="male"  
  39.             checked={this.state.gender === "male"}  
  40.             onChange={this.onChangeHandler}  
  41.           />  
  42.           <label>Female</label>  
  43.           <input  
  44.             type="radio"  
  45.             name="gender"  
  46.             value="female"  
  47.             checked={this.state.gender === "female"}  
  48.             onChange={this.onChangeHandler}  
  49.           />  
  50.           <br />  
  51.           <br />  
  52.           <label>State: </label>  
  53.           <select  
  54.             name="state"  
  55.             value={this.state.state}  
  56.             onChange={this.onChangeHandler}  
  57.           >  
  58.             <option value="Maharashtra">Maharashtra</option>  
  59.             <option value="Madhya Pradesh">Madhya Pradesh</option>  
  60.             <option value="Karnataka">Karnataka</option>  
  61.             <option value="West Bengal">West Bengal</option>  
  62.           </select>  
  63.         </form>  
  64.         <br />  
  65.         <hr />  
  66.         <p>State of Component</p>  
  67.         <pre>{JSON.stringify(this.state, null, 2)}</pre>  
  68.       </div>  
  69.     );  
  70.   }  
  71. }  
  72.   
  73. export default ControlledFormComponent;  
 

Using React Hooks

 
We can also handle the form state using React hooks. To do that we have useState() hook for storing state in a functional component. 
 
Now we will create a simple form with one input element and handle its data using a hook. 
  1. import React, { useState } from 'react';  
  2.   
  3. export default function ControlledFormWithHook() {  
  4.   const [name, setName] = useState('');  
  5.   
  6.   return (  
  7.     <div>  
  8.       <form>  
  9.         <label>Name:</label>  
  10.         <input type="text" onChange={(e) => setName(e.target.value)} />  
  11.       </form>  
  12.       <br />  
  13.       Name is: {name}  
  14.     </div>  
  15.   );  
  16. }  
Here we have used a useState() hook to handle state.

Forms using Uncontrolled Components

 
We know that HTML elements maintain their own state and update state when an input value changes. So we can directly access the value of the HTML element without maintaining the component state. When data is handled by DOM elements then we can call this as Uncontrolled component. React provides ref to directly get the reference of the DOM element. So in Uncontrolled component, state is stored in the DOM rather than in the component state. In some of the cases, we have to use the uncontrolled component, for example when you want to add select file functionality; i.e <input type="file" />.
 
Now we will take the same example that we have implemented in controlled component and change it to use uncontrolled component using React.createRef() API.
 
Final code is, 
  1. import React, { Component } from "react";  
  2.   
  3. export default function UncontrolledFormComponent() {  
  4.   let inputRef = React.createRef();  
  5.   let name = "";  
  6.   const handleClick = e => {  
  7.     e.preventDefault();  
  8.     alert("Name is: " + inputRef.current.value);  
  9.   };  
  10.   
  11.   return (  
  12.     <div>  
  13.       <h3>Uncontrolled Form Component</h3>  
  14.       <form>  
  15.         <input type="text" ref={inputRef} />  
  16.         <button style={{ margin: "8px" }} onClick={handleClick}>  
  17.           Submit  
  18.         </button>  
  19.       </form>  
  20.     </div>  
  21.   );  
  22. }  
When you click on submit button then the alert box is opened showing the value you have entered in a textbox. 
 
To know more about Refs in react you can check out my below articles,

Conclusion

 
In this article, I have explained about Forms in React JS and also discussed different ways to handle forms in react.
 
I really hope that you enjoyed this article, share it with friends and please do not hesitate to send me your thoughts or comments.
 
This article was originally published on my blog
 
You can follow me on twitter @sumitkharche01
 
Happy Coding!