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.
- 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>
)
}
- 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>
)
}
See images below
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
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
See the images below
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
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
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
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
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
See images below
Top comments (0)