3

I want to implement useRef so that the component in which my input tag is should not re-render on value change. If we use useState it will re-render the entire component on every key pressed.

This is how we usually do it but this will re-render the entire component on every change.

const [name, setName] = useState('');
return(
   <input type="text" placeholder="Name" value={name} onChange={e => setName(e.target.value)} />   
)

I want to do this using useRef to avoid it

const name = useRef("");
const handleName = (e) => {
   name.current = e.target.value
 };

return(
   <input type="text" placeholder="Name" value={name.current.value} onChange={handleName} />   
)

but it's not working for some reason?

Pinak faldu
  • 79
  • 1
  • 7
  • Why do you want to avoid the re-render? – ollie Mar 21 '22 at 14:06
  • I am learning react hooks and I think why to re-render the entire component if we can achieve this using useRef with re-render I think? I may be wrong! – Pinak faldu Mar 21 '22 at 14:13
  • The `input` element takes care of re-rendering itself on every value change, you don't need to pass the updated value to it, it handles it's own state. – HedeH Mar 21 '22 at 14:41

2 Answers2

3

Change your input tag to this (inside JSX):

     <input type="text" placeholder="Name" ref={name} onChange={handleName} />   

Instead of value={name.current.value} use ref={name}. It should fix the issue.

Full code :

import { useRef } from "react";

export default function App() {

  const name = useRef('');

  const handleName = (e) => {
     name.current = e.target.value
     document.getElementById('test').innerText = name.current
   };
  
  return(
    <>
     <input type="text" placeholder="Name" ref={name} onChange={handleName} />   
     <p id='test'></p>

     </>
  )
  
}
Ankit Saxena
  • 1,067
  • 1
  • 4
  • 16
  • 1
    Yes, it is working as I said but can we display the current value of input value like in p tag using this. – Pinak faldu Mar 21 '22 at 14:44
  • You can try this by giving an ```id``` to your p tag. const handleName = (e) => { name.current = e.target.value document.getElementById('test').innerText = name.current }; return( <>

    >
    – Ankit Saxena Mar 21 '22 at 15:27
  • either the above way or you can try the ```dangerouslySetInnerHTML``` property of react. (I have updated my answer using the ```id``` approach) you can check here for more info about it - https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml – Ankit Saxena Mar 21 '22 at 15:41
0

if you want to avoid rendering on change, you can just pass ref to the input element. and whenever required you can get the value from ref as used in the handleSubmit method below. Html input element will maintain its state:

    const nameRef = useRef(null);
const handleSubmit = () => {
  console.log(nameRef.current.value);
};

return(
   <input type="text" ref={nameRef}  placeholder="Name" />   
)
  • const nameRef = useRef(null); const handleSubmit = () => { console.log(nameRef.current.value); }; return( ) – user3349616 Mar 21 '22 at 14:17
  • This is working as it suppose to be but if you have to give a p tag that displays the current value of the input tag then it's not working as

    {nameRef.current.value}

    – Pinak faldu Mar 21 '22 at 14:33
  • if you want to display the value on change then you need to render and maintain the name state – user3349616 Mar 21 '22 at 19:40