While React refs are primarily used to interact with DOM elements, useRef
can also be used to store values in your function components.
Unlike useState
, when this value changes the component will not re-render, which means you can leverage useRef
to avoid unnecessary renders and optimize your application's performance.
// Instantiate useRef
const countRef = useRef(0)
// Increment the value while avoiding a re-render
countRef.current = countRef.current + 1
Ryan Harris: [0:00] In this component, we have two counters. One is being kept track of by this ref here, refValue, which has an initial value of , and the other is being tracked by this state hook, which also has an initial value of .
[0:14] To illustrate how useState causes a re-render whereas useRef doesn't, I'm going to add two more states here to keep track of hex values that I'll use for my styles.
[0:26] First, we'll say const [ refHex, setRefHex] = useState() and we'll call this randomColor() utility function. Then we're also going to say const [ stateHex, setStateHex] = useState(randomColor()).
[0:51] Now that we're storing these values, let's use them in these style objects I've created down here and assigned to DOM elements below, so that we can see the colors change when the component re-renders.
[1:02] We'll say background: I can copy that and come down to our stateStyles and we'll do the same thing except it'll be the stateHex. Now when I save this, you'll see that each of these divs now has a different background color.
[1:22] In order to see when our component is re-rendering more easily, let's use a couple of fact hooks to change the background colors when these values change. First, we'll say useEffect(() => { setRefHex(randomColor)}).
[1:44] In the dependency array, we only want this to fire when the refValue changes. Then we'll use another useEffect here to do the same for our state. We'll say, setStateHex(randomColor) and the dependency array will be the stateValue.
[2:08] I've already wired up the + and - buttons. If I update the stateCounter here by clicking the + button, notice that the background color changes, and same if I click the - button.
[2:26] If I click the ref button, nothing seems to happen. Let's click it again and one more time. If we were using the useState hook here, I would expect this value to be 3, but because we're changing a refValue, we're not causing a re-render. Let's press the state button one more time to cause a re-render. You'll actually see that the refValue has now updated.
[2:52] In summary, useRef can be used to store data values just like useState, but the difference is that when that value changes, it doesn't cause a re-render. This can be used as a performance optimization when you're keeping track of internal values in a component, but you don't want it to re-render every time the value changes.