The useRef hook returns an object, and this object contains a special property named ".current". The ".current" property gets initialized with the initial value that we pass into the useRef hook. If no initial value is passed then its value is set to "undefined".
// if initial value is passed
const reference = useRef(4); // return { current : 4}
console.log(reference.current); // logs 4 to console
// if no initial value passed
const reference = useRef(); // return {current : undefined}
console.log(reference.current); // logs undefined to console
The useRef hook is mainly used for:
- Creating a mutable persistent variable
- Accessing the DOM elements
Creating a mutable persistent variable
The important thing about the reference object:
- Updating it doesn't re-render the component while on the other hand, updating the state variable triggers re-rendering.
- It persists between component re-rendering.
import { useRef } from 'react';
function Counter() {
const countRef = useRef(0);
const handler = () => {
countRef.current++;
console.log(`Clicked ${countRef.current} times`);
};
console.log('Counter rendered!');
return <button onClick={handler}> Increment </button>;
}
In the above example, when we click on the button, the value of "countRef.current" is incremented. But the component doesn't re-render. It renders only once.
if we use state variable to implement the above example, then every time we click the increment button, the count value changes and it trigger re-rendering.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const handler = () => {
setCount( state => state+1);
console.log(`Clicked ${count} times`);
};
console.log('Counter rendered!');
return <button onClick={handler}> Increment </button>;
}
Accessing the DOM element
We can use the following steps to access a DOM element. First, we create a reference object using the useRef hook.
const reference = useRef();
Then, we assign the reference object to a DOM element to its 'ref' attribute.
<p ref={reference}> hello world!</p>
And React will initialize the ".current" property with this element.
import { useRef, useEffect } from 'react';
function RefDemo() {
const reference = useRef();
useEffect(() => {
const element = reference.current;
console.log(element); // it will logs <p>Hello, world!</p>
}, []);
return (
<p ref={reference}>
Hello, world!
</p>
);
}
Note:
Just like the states, the reference object must be updated inside the useEffect() callback or a handler function.