React's useRef
hook is used to store references to DOM elements. But did you know you can store and update values with useRef
?
Storing element references with useRef
As the name suggests, useRef
can store a reference to a DOM element. To do this, create the ref, and then pass it into the element:
const Component = () => {
const ref = useRef(null);
return <div ref={ref}> Hello world </div>;
};
With this reference, you can do lots of useful things like:
- Grabbing an element's height and width
- Seeing whether a scrollbar is present
- Calling
focus()
on the element at a certain moment
Storing and updating values with useRef
Another use-case for useRef
allows us to store values, which you can later use and change:
const Component = () => {
const ref = useRef({
renderCount: 0
});
// Increase the render count on every re-render
ref.current.renderCount += 1;
return <>Hello world</>;
}
To change the ref's value, you will need to change ref.current
(and not ref
itself!)
useRef vs useState: What's wrong with useState?
The key difference between useState
and useRef
is that:
- If you update the state, your component will re-render
- If you update the value stored in your ref, nothing will happen
If you don’t need the component to re-render (or you don't want the component to re-render), useRef
may be a good candidate.
What’s the difference between useRef and using a variable?
If you tried initializing a variable like this:
const Component = () => {
let renderCount = 0;
renderCount += 1;
return <>Hello world</>;
}
It would get end up getting re-initialized each time the component renders. If you use a ref, the value you store in it will persist between renders of your component.
What about if I define the variable outside of the component?
If you initialize the value outside of your component, this value will be global to all instances of Component
.
So if you change the value, it will affect the value for all the other components you have rendered on your page.
let renderCount = 0;
const Component = () => {
// If you had 10 Components on the page, they would all update the same
// renderCount value and it would already be at 10 after one render!
renderCount += 1;
return <>Hello world</>;
}
useRef vs createRef
createRef
is the API that React provided for refs before hooks came around:
import { createRef } from 'react';
class Component extends React.Component() {
ref = createRef();
render() {
this.ref.renderCount += 1;
return <div>Hello world</div>;
}
}
If you're using functional components I would recommend using useRef
over createRef
.
How to use useRef in class components
As useRef
is a hook, it will only work with functional components.
With class components, you can use the createRef()
example I showed above.
You can also achieve the same thing using a class variable:
class Component extends React.Component() {
renderCount = 0;
render() {
this.renderCount += 1;
return <div>Hello world</div>;
}
}