DEV Community

Himanshupal0001
Himanshupal0001

Posted on

How to handle re-renders in react forms? 🚀

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
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>
    )
}
Enter fullscreen mode Exit fullscreen mode
  1. FormInput.jsx
import React from 'react'
import './FormInput.scss'
function FormInput(props) {

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

See images below

Image description

Image description

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

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
Enter fullscreen mode Exit fullscreen mode

FormInput.jsx

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

Enter fullscreen mode Exit fullscreen mode

See the images below

Image description

Image description

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

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
Enter fullscreen mode Exit fullscreen mode

FormInput.jsx

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

Enter fullscreen mode Exit fullscreen mode

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

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

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

See images below

Image description

Top comments (0)