What is useRef hook?
The `useRef` hook in React provides a way to create mutable ref objects that can persist a value across re-renders without causing the component to re-render when the ref's value changes. It's primarily used for direct interaction with the DOM or to store any mutable value that doesn't need to trigger UI updates.
What is `useRef`?
The useRef hook returns a mutable ref object whose .current property is initialized to the argument passed (initialValue). The returned object will persist for the full lifetime of the component. Unlike useState, updating the .current property of a ref does not trigger a re-render of the component.
This makes useRef ideal for storing values that you want to keep track of across renders, but whose changes should not cause a re-render. It's like an instance variable for a functional component.
Common Use Cases
Accessing DOM Elements
This is perhaps the most common use case. useRef allows you to directly interact with DOM nodes or React components. When you attach a ref to an element using the ref prop, React will place the DOM element into the .current property of the ref object.
import React, { useRef, useEffect } from 'react';
function MyComponent() {
const inputRef = useRef(null);
useEffect(() => {
// Focus the input element when the component mounts
if (inputRef.current) {
inputRef.current.focus();
}
}, []);
return (
<div>
<input type="text" ref={inputRef} />
<button onClick={() => alert(inputRef.current.value)}>Get Input Value</button>
</div>
);
}
Storing Mutable Values That Don't Trigger Re-renders
You can use useRef to store any value that needs to persist across renders but doesn't need to trigger a UI update when it changes. Examples include timers, interval IDs, previous state values, or any object that you want to keep a consistent reference to.
import React, { useRef, useState } from 'react';
function CounterWithoutRender() {
const counterRef = useRef(0);
const [_, setRerender] = useState(false); // Dummy state to force re-render
const increment = () => {
counterRef.current = counterRef.current + 1;
console.log('Counter value (no re-render):', counterRef.current);
};
const forceRerender = () => {
setRerender(prev => !prev); // Toggles state to force re-render
};
return (
<div>
<p>Ref Counter Value: {counterRef.current}</p>
<button onClick={increment}>Increment Ref Counter (No Re-render)</button>
<button onClick={forceRerender}>Force Re-render (to see ref value updated)</button>
<p>(Note: The paragraph above won't update until a re-render is triggered by something else)</p>
</div>
);
}
Referencing the Previous Value of Props or State
A common pattern is to use useRef in conjunction with useEffect to store the previous value of a prop or state variable, allowing you to compare current and previous values in subsequent renders.
Key Characteristics
- Returns a mutable ref object whose
.currentproperty is initialized to the passed argument (initialValue). - The returned ref object will persist for the full lifetime of the component.
- Updating a ref's
.currentvalue does *not* trigger a re-render of the component. useRefdoes *not* notify you when its content changes; you typically useuseEffectif you need side effects based on changes to the ref's value.
Syntax
const myRef = useRef(initialValue);
Summary
In essence, useRef is a powerful hook for storing values that need to persist across renders without causing the component to re-render upon update. It's a fundamental tool for managing direct DOM interactions and maintaining mutable, non-reactive data within functional components.