Forms in React
Tags: react, webdev, javascript, beginners
Published: 2020-02-29 17:34:06

In this article, we will be discussing more about forms in React and different way to create and handle forms in React. So let's grab the 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:

```html
<form>
  <label for="name">Name:</label><br>
  <input type="text" id="name" name="name" value="John"><br>
  <input type="submit" value="Submit">
</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 and also see how to create forms in React. 

Let's get started.

## TL;DR
* [Source code](https://stackblitz.com/edit/react-forms-tutorial?file=index.js)

## 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 way:

1. Forms using Controlled Components
2. 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 forms elements contains. So when data of forms elements is handled by react component then it is called as 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 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:

```javascript
import React, { Component } from "react";

class ControlledFormComponent extends Component {
  render() {
    return (
      <div>
        <h3>Controlled Component</h3>
        <br />
        <form>
          <label>Student Name: </label>
          <input type="text" placeholder="enter student name" />
        </form>
      </div>
    );
  }
}

export default ControlledFormComponent;

```
It looks something like:

![form1](https://dev-to-uploads.s3.amazonaws.com/i/2ovg320idxquurr65tyn.PNG)


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 change event on the input element to change the state of a component when the value of input element changed. To see whats in state object print the state in bottom of the form.


```javascript
import React, { Component } from "react";

class ControlledFormComponent extends Component {

  constructor(props) {
    super(props);
    this.state = {
      studentName: ""
    };
    this.onNameChangeHandler = this.onNameChangeHandler.bind(this);
  }

  onNameChangeHandler(e){
    this.setState({
      studentName: e.target.value
    })
  }

  render() {
    return (
      <div>
        <h3>Controlled Component</h3>
        <br />
        <form>
          <label>Student Name: </label>
          <input 
              type="text" 
              placeholder="enter student name"
              onChange={this.onNameChangeHandler} />
        </form> 
        <hr/>
        <p>State of Component</p>      
          <pre>{JSON.stringify(this.state, null, 2) }</pre>     
      </div>
    );
  }
}

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.

![input-element](https://dev-to-uploads.s3.amazonaws.com/i/7v3r3uc6d13u5qemvw67.gif)

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 property in the state for holding data of our new elements i.e gender and state. 

```html
         <label>Gender: </label>
          <label>Male</label>
          <input
            type="radio"
            name="gender"
            value="male"
            checked={this.state.gender === "male"}
            onChange={this.onChangeHandler}
          />
          <label>Female</label>
          <input
            type="radio"
            name="gender"
            value="female"
            checked={this.state.gender === "female"}
            onChange={this.onChangeHandler}
          />
          <br />
          <br />
          <label>State: </label>
          <select
            name="state"
            value={this.state.state}
            onChange={this.onChangeHandler}
          >
            <option value="Maharashtra">Maharashtra</option>
            <option value="Madhya Pradesh">Madhya Pradesh</option>
            <option value="Karnataka">Karnataka</option>
            <option value="West Bengal">West Bengal</option>
          </select>
```
Adding the seperate change event handler function for HTML element is not correct approach. We will add only one handler function to handle all our HTML element change events.

```javascript
onChangeHandler(e){
    this.setState({
      [e.target.name]: e.target.value
    })
  }
```
So the final component is look like below:

```javascript
import React, { Component } from "react";

class ControlledFormComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      studentName: "",
      gender: "",
      state: "Maharashtra"
    };
    this.onChangeHandler = this.onChangeHandler.bind(this);
  }
  onChangeHandler(e) {
    this.setState({
      [e.target.name]: e.target.value
    });
  }
  render() {
    return (
      <div>
        <h3>Controlled Component</h3>
        <br />
        <form>
          <label>Student Name: </label>
          <input
            type="text"
            name="studentName"
            placeholder="enter student name"
            onChange={this.onChangeHandler}
          />
          <br />
          <br />
          <label>Gender: </label>
          <label>Male</label>
          <input
            type="radio"
            name="gender"
            value="male"
            checked={this.state.gender === "male"}
            onChange={this.onChangeHandler}
          />
          <label>Female</label>
          <input
            type="radio"
            name="gender"
            value="female"
            checked={this.state.gender === "female"}
            onChange={this.onChangeHandler}
          />
          <br />
          <br />
          <label>State: </label>
          <select
            name="state"
            value={this.state.state}
            onChange={this.onChangeHandler}
          >
            <option value="Maharashtra">Maharashtra</option>
            <option value="Madhya Pradesh">Madhya Pradesh</option>
            <option value="Karnataka">Karnataka</option>
            <option value="West Bengal">West Bengal</option>
          </select>
        </form>
        <br />
        <hr />
        <p>State of Component</p>
        <pre>{JSON.stringify(this.state, null, 2)}</pre>
      </div>
    );
  }
}

export default ControlledFormComponent;

```

![final-output](https://dev-to-uploads.s3.amazonaws.com/i/rs1uhesomo00dx7u0a8m.gif)

#### 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.

```javascript
import React, { useState } from 'react';

export default function ControlledFormWithHook() {
  const [name, setName] = useState('');

  return (
    <div>
      <form>
        <label>Name:</label>
        <input type="text" onChange={(e) => setName(e.target.value)} />
      </form>
      <br />
      Name is: {name}
    </div>
  );
}
```
Here we have used a `useState()` hook to handle state.

![Hook-1](https://dev-to-uploads.s3.amazonaws.com/i/cmglfk3m1r3bhy6nnrkd.PNG)

## 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 :

```javascript

import React, { Component } from "react";

export default function UncontrolledFormComponent() {
  let inputRef = React.createRef();
  let name = "";
  const handleClick = e => {
    e.preventDefault();
    alert("Name is: " + inputRef.current.value);
  };

  return (
    <div>
      <h3>Uncontrolled Form Component</h3>
      <form>
        <input type="text" ref={inputRef} />
        <button style={{ margin: "8px" }} onClick={handleClick}>
          Submit
        </button>
      </form>
    </div>
  );
}

```

When you click on submit button then the alert box is opened showing the value you have entered in a textbox.

![form-3](https://dev-to-uploads.s3.amazonaws.com/i/qqzzhfuu3viif7qiwhb2.PNG)

To know more about Refs in react you can check out my below articles:

{% link https://dev.to/sumitkharche/different-ways-to-create-refs-in-react-11l5 %}


{% link https://dev.to/sumitkharche/forwarding-refs-in-react-1p0b %}

## 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.

You can follow me on twitter [@sumitkharche01](https://twitter.com/sumitkharche01)

Happy Coding!