One of the most powerful hooks in the React ecosystem is the useRef hook. This hook allows you to create a reference to a DOM element or a component instance, which can be used to access and manipulate the element or component in various ways.
Understanding the basics of the useRef hook
The useRef hook is a simple hook that takes an initial value as an argument and returns a ref object. The ref object has a single property called "current" that stores the initial value. The value of "current" can be updated at any time, and the hook will not re-render the component.
import { useRef } from 'react';
function MyComponent() {
const myRef = useRef('initial value');
return (
<div>
<p>{myRef.current}</p>
<button onClick={() => myRef.current = 'new value'}>Update value</button>
</div>
);
}
In the example above, we created a ref called myRef
with an initial value of initial value
. We then used the current
property of the ref to display the value in a <p> tag and update the value when a button is clicked.
It's important to note that the useRef return a plain javascript object, that's why you can store any type of data inside it.
Using useRef to access and manipulate DOM elements
One of the most common uses of the useRef hook is to access and manipulate DOM elements. When you create a ref to a DOM element, you can use the "current" property of the ref to access the element and perform various operations on it, such as setting focus, measuring dimensions, and more.
import { useRef } from 'react';
function MyInput() {
const inputRef = useRef(null);
function handleClick() {
inputRef.current.focus();
}
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleClick}>Focus input</button>
</div>
);
}
We created a ref called inputRef
with an initial value of null. We then used the ref
attribute to assign the ref to an <input> element. When the button is clicked, we use the current
property of the ref to set focus on the input.
Using useRef to access and manipulate component instances
Another common use of the useRef hook is to access and manipulate component instances. When you create a ref to a component, you can use the current
property of the ref to access the component instance and perform various operations on it, such as calling methods, accessing state, and more.
import { useRef } from 'react';
function MyCounter() {
const counterRef = useRef(null);
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
counterRef.current.reset();
}
return (
<div>
<Counter ref={counterRef} count={count} />
<button onClick={handleClick}>Increment and reset</button>
</div>
);
}
function Counter({ count, ref }) {
const [localCount, setLocalCount] = useState(count);
function reset() {
setLocalCount(0);
}
return (
<div ref={ref}>
<p>{localCount}</p>
</div>
);
}
In the a above example, we created a ref called counterRef
with an initial value of null. We then passed the ref as a prop to a custom component called Counter
. When the button is clicked, we use the current
property of the ref to call the reset
method on the Counter
component instance, which sets the local count back to 0.
When to use
Accessing and manipulating DOM elements: The useRef hook can be used to create a reference to a DOM element, which can then be used to access and manipulate the element. This can be useful for things like setting focus on an input field, measuring the dimensions of an element, or manipulating the element's style.
Accessing and manipulating component instances: The useRef hook can also be used to create a reference to a component instance, which can then be used to access and manipulate the component. This can be useful for things like calling methods on the component, accessing the component's state, or manipulating the component's props.
Storing values that change over time: The useRef hook can be used to store values that change over time, but should not trigger a re-render. This can be useful for things like storing a timer ID, a WebSocket connection, or other values that are not directly related to the component's state.
Storing mutable data: The useRef hook returns a plain javascript object, it can store any type of data, and it doesn't re-render when its value changes, it can be used to store mutable data, like a canvas element, an audio context, and others.
Avoiding unnecessary re-renders: Because the useRef hook does not trigger a re-render when its value changes, it can be used to store values that are used in a component's render method, but should not trigger a re-render when they change. This can help to improve the performance of your application.
When not to use
Storing state that should trigger a re-render: The useRef hook should not be used to store state that should trigger a re-render. For that purpose, the useState hook should be used instead. The useState hook is intended for values that change over time and should trigger a re-render.
Values that are only used in a single render: If a value is only used in a single render, it does not need to be stored in a ref. Instead, it can be passed as a prop or calculated on-the-fly.
Values that are only used in a single render and don't change over time: If a value is only used in a single render and does not change over time, it does not need to be stored in a ref. Instead, it can be defined as a constant.
When the value is not mutable: The useRef is useful when the value is mutable, like a canvas element, an audio context, and others. If the value is immutable, there's no need to use the useRef hook, you can use useState or a plain variable instead.
When the value will be changed very frequently: The useRef only updates the value when the component re-renders, if you have a value that will change frequently, it could cause performance issues.
Further Readings
https://beta.reactjs.org/reference/react/useRef