How to handle re-renders in react forms? 🚀
Tags: react, tutorial, webdev, javascript
Published: 2023-01-18 08:21:54

Today we gonna learn about how to handle forms in react. We specifically focus on handling re-renders. Re-rendering is not a bad thing in react, after all it's the very nature of react. But you might want not to re-render a component every time when the state change. There are two ways you can avoid re-renders. Keep in mind that if a state is not affecting any other state or component it's ok that a component re-renders.

## Create a basic form

> I created a component called FormInput and a page called form. FormInput will be called in form page.

1. Form.jsx 
```js
import React, { useEffect, useRef, useState } from 'react'
import './Form.scss'
import FormInput from './FormInput'
function Form() {

    return (
        <form>
            <div className='form'>
                <FormInput placeholder='username' />
                <FormInput placeholder='email' />
                <FormInput placeholder='full name' />
            </div>
        </form>
    )
}
```

2. FormInput.jsx
```js
import React from 'react'
import './FormInput.scss'
function FormInput(props) {

    return (
        <div className='formInput'>
            {/* <label>User Name</label> */}
            <input placeholder={props.placeholder}  />
        </div>
    )
}
```

> See images below

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2vtncadshz5h6ulayk7.gif)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ycgbd4a76jq3qok134q8.PNG)

As you can see there is no rendering going on. We need to give state to the input for make it happen.

## Adding state in the form

> Form.jsx
```js
import React, { useEffect, useRef, useState } from 'react'
import './Form.scss'
import FormInput from './FormInput'
function Form() {

    const [username, setUsername] = useState('');
    const [email, setEmail] = useState('');
    const [fullname, setFullname] = useState('');
    console.log('re-rendering', username);
    console.log('re-rendering', email);
    console.log('re-rendering', fullname);
    return (
        <form>
            <div className='form'>
                <FormInput placeholder='username' input={setUsername} />
                <FormInput placeholder='email' input={setEmail} />
                <FormInput placeholder='full name' input={setFullname} />
            </div>
        </form>
    )
}

export default Form
```

> FormInput.jsx

```js
import React from 'react'
import './FormInput.scss'
function FormInput(props) {

    return (
        <div className='formInput'>
            {/* <label>User Name</label> */}
            <input placeholder={props.placeholder} onChange={e => props.input(e.target.value)} />
        </div>
    )
}

export default FormInput

```

> See the images below

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fk57yb3lhvoub445x61o.gif)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dqhi3y0f58cv5tij0n0k.PNG)

As you can see there are three states and all are rendering parallelly. Even if there's change in one state all states re-render. You might want to stop the re-rendering want to render the component only once. For this we will use below approches


## Use useRef instead of useState.

> Form.jsx

```js
import React, { useEffect, useRef, useState } from 'react'
import './Form.scss'
import FormInput from './FormInput'
function Form() {
    const usernameref = useRef();
    const emailref = useRef();
    const fullnameref = useRef();


    const handleSubmit = e => {
        e.preventDefault();
        console.log(usernameref);
        console.log(emailref);
        console.log(fullnameref);
    }
    return (
        <form onSubmit={handleSubmit}>
            <div className='form'>
                <FormInput placeholder='username' refer={usernameref} />
                <FormInput placeholder='email' refer={emailref} />
                <FormInput placeholder='full name' refer={fullnameref} />
                <button>Submit</button>
            </div>
        </form>
    )
}

export default Form
```

> FormInput.jsx

```js
import React from 'react'
import './FormInput.scss'
function FormInput(props) {

    return (
        <div className='formInput'>
            {/* <label>User Name</label> */}
            <input placeholder={props.placeholder} ref={props.refer} />
        </div>
    )
}

export default FormInput

```
As you can see I removed useState() and used useRef(). UseRef() can only render once when page reload so I prevent form to refresh unless submit button pressed. 
> See images below


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/66ohnclljpngrn4jg4mk.PNG)

Check the console. All the inputs render only once.

## Using Object method

Instead useRef we can also use Objects using new keyword. We can create object of the input from form.

> Form.jsx

```js
import React, { useEffect, useRef, useState } from 'react'
import './Form.scss'
import FormInput from './FormInput'
function Form() {


    const handleSubmit = e => {
        e.preventDefault();
        const data = new FormData(e.target);
        console.log(Object.fromEntries(data.entries()));
    }
    return (
        <form onSubmit={handleSubmit}>
            <div className='form'>
                <FormInput placeholder='username' name='username' />
                <FormInput placeholder='email' name='email' />
                <FormInput placeholder='full name' name='fullname' />
                <button>Submit</button>
            </div>
        </form>
    )
}

export default Form
```

> FormInput.js

```js
import React from 'react'
import './FormInput.scss'
function FormInput(props) {

    return (
        <div className='formInput'>
            {/* <label>User Name</label> */}
            <input placeholder={props.placeholder} name={props.name} />
        </div>
    )
}

export default FormInput

```

> See images below


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hxvjut3vgzc2k3quxc3p.PNG)