Photo by Brianna Santellan on Unsplash
In this post we?ll cover what the useRef Hook is, what we can use it for and some advice for using it.
The useRef Hook is a function that returns a mutable ref object whose .current property is initialized with the passed argument (initialValue). The returned object will persist for the full lifetime of the component.
const refContainer = useRef(initialValue);
There are two main uses of useRef that are explained in the following sections: Accessing the DOM nodes or React elements and keeping a mutable variable.
Accessing the DOM nodes or React elements
If you?ve worked with React for a while, you might be used to using refs for this purpose. Below there?s an example of the use of refs in class components:
And its equivalent using a functional component:
?Notice that with a functional component we are using useRef instead of createRef. If you create a ref using createRef in a functional component, React will create a new instance of the ref on every re-render instead of keeping it between renders.
Keeping a mutable variable
Both in class components and functional components using Hooks, we have two ways of keeping data between re-renders:
In class components
- In the component state: Every time the state changes, the component will be re-rendered.
- In an instance variable: The variable will persist for the full lifetime of the component. Changes in an instance variable won?t generate a re-render.
In functional components
The equivalent ways in functional components using Hooks:
- In a state variable: useState or useReducer. Updates in state variables will cause a re-render of the component.
- In a ref: Equivalent to instance variables in class components. Mutating the .current property won?t cause a re-render.
Below is an example of keeping a mutable variable in a ref. The component <Timer> initializes a setInterval on every re-render and needs to implement a callback to stop its interval imperatively:
Updating a ref
In the Hooks FAQ Is there something like instance variables? this is mentioned:
?Unless you?re doing lazy initialization, avoid setting refs during rendering ? this can lead to surprising behavior. Instead, typically you want to modify refs in event handlers and effects.?
Why is that? To understand it, we need to do a brief refresh of the React component lifecycle with Hooks:
The ?Render phase? may be restarted by React so it has to be pure, it can?t have side effects.
Updating a ref value is a side effect.
All side effects should be done in the ?Layout phase? or in the ?Commit phase?; inside useLayoutEffect or the useEffect when using React Hooks.
Here is the right version of the example above:
Summing up
The useRef Hook lets us create mutable variables inside functional components. There are three main key points that you should keep in mind when using the useRef Hook:
- A ref created with useRef will be created only when the component has been mounted and preserved for the full lifecycle.
- Refs can be used for accessing DOM nodes or React elements, and for storing mutable variables (like with instance variables in class components).
- Updating a ref is a side effect so it should be done only inside a useEffect (or useLayoutEffect) or inside an event handler.