useRef hook for working with refs in React
In this lesson we'll work with refs. For clarity, let's look at how the useRef hook works compared to the useState hook.
Let's create a component with a button:
return (
<div>
<button>
state click
</button>
</div>
);
We import into the component useState:
import { useState } from 'react';
And let’s create a state state:
const [state, setState] = useState(0);
Now let's make it so that when we click on the button, our state would increase by 1. We will display the state value directly in the button text:
<button onClick={handleStateClick}>
state click: {state}
</button>
Let's describe the function for handling a click on the button handleStateClick:
function handleStateClick() {
setState(state + 1);
}
We press the button and see how the state value grows.
Now let's create a App component, but using a ref instead of a state.
First, import useRef into the component:
import { useRef } from 'react';
And we'll create a ref ref. The hook useRef returns a ref object with a single property current, which we'll be interested in later. We'll set its initial value to 0:
const ref = useRef(0);
Let's attach a click handler to the button. Remember that we have to read/change not ref itself, but its property current:
<button onClick={handleRefClick}>
ref click: {ref.current}
</button>
Let's add a function to handle a click on our button. Here we will increase current by 1, as in the previous example with the state. Unlike the state, where the setState function is required to change its value, we work directly with the ref property:
function handleRefClick() {
ref.current = ref.current + 1;
}
Now we press our button. And what do we see? When we click on it, as we initially had 0, it does not change.
You may, of course, start to doubt that the value changes at all. Let's check this. To do this, in the click handler function, we'll add another line of code that outputs the value of current to the console:
function handleRefClick() {
ref.current = ref.current + 1;
console.log('ref click: ' + ref.current);
}
Now, having opened the console in the browser, we click on the button again and make sure that the value really changes with each click and there is no deception.
Now we see that, unlike the state, changing the ref value does not cause the component to render. So we see the initial value 0 in the button text every time.
So if your data is used for rendering, then store it in the state, and if you don't need rendering, then using refs can be more efficient.
Let's say your component has a paragraph with text 'text' and a button. Make it so that every time the button is clicked, an exclamation mark is added to the end of the paragraph text. Do this using state.
Create a App component, but instead of state, now use ref. Make sure that when you click the button, the paragraph text does not change. Also add output of the paragraph text to the console, open it and make sure that the text actually changes.