How do the useRef and useState hooks differ in React?
In browsers, JavaScript provides smart and efficient access to useRef hooks to help access the DOM nodes directly and avoid re-rendering the entire component. The useRef hook creates an object with a single property called current and stores the value of the element that is referenced inside the current property.
Example of useRef hooks
First, you need to create a simple useRef hook in a React component, as shown below:
import React, {useRef} from 'react'
function UseRefDemo() {
const countRef = useRef(0);
const countClick= () => {
countRef.current++;
console.log(`Button was clicked ${countRef.current} times`);
}
console.log('Component rendered!')
return (
<div>
<h1>useRef Demo</h1>
<button onClick={countClick}>Click Me!!</button>
</div>
)
}
export default UseRefDemo
The component above involves the following actions:
- Use the
useRefhook to define a variablecountRefand set its initial value to . - Create a button that tracks the number of times it is clicked.
- Define the
countClickfunction, which is called each time the button is clicked. - The
countRef.currentproperty logs the current value of the button and increments it each time the button is clicked. - The
console.logstatement that prints “Component rendered” is only invoked once, which demonstrates that this component is not re-rendered unnecessarily with every click, as shown below:

Example of useState hooks
To adapt the previous example to use a useState hook, you need to define a count state variable and set its initial value to zero. The value of this variable is incremented each time the button is clicked.
The adapted code with the useState hook is shown below:
import React, {useState} from 'react'
function UseRefDemo() {
const [count,setCount] = useState(0);
const countClick= () => {
const countClicks = count+1;
setCount(countClicks);
console.log(`Button was clicked ${countClicks} times`);
}
console.log('Component rendered!')
return (
<div>
<h1>useRef Demo</h1>
<button onClick={countClick}>Click Me!!</button>
</div>
)
}
export default UseRefDemo
The output of the component above is as follows:

Although the result is the same as when we use the useRef hook, the component re-renders each time the button is clicked and the console.log statement is invoked multiple times.