useRef is a React hook that persists values between renders without causing re-renders. It’s commonly used beyond simple value storage.
What does useRef do?
Unlike useState, updating current doesn’t trigger a re-render. Common use cases:
- DOM access: e.g., focusing inputs.
- Mutable values: timers, previous props, counters.
- State persistence: maintain data across renders without affecting UI.
Basic Usage
import React, { useRef } from 'react';
function MyComponent() {
const myRef = useRef(initialValue);
return {/* ... */};
}
useRef(initialValue): initializes the ref (.current).myRef.current: access/update value without re-rendering.
Accessing DOM Elements
import React, { useRef, useEffect } from 'react';
function FocusInput() {
const inputEl = useRef(null);
useEffect(() => inputEl.current.focus(), []);
return ;
}
ref={inputEl}: attach ref to DOM.useEffect: ensures element exists before interacting.
Storing Mutable Values
import React, { useRef, useState, useEffect } from 'react';
function PreviousValue() {
const [count, setCount] = useState(0);
const previousCount = useRef(0);
useEffect(() => previousCount.current = count, [count]);
return (
Current: {count}
Previous: {previousCount.current}
);
}
useRef vs useState
| Feature | useState | useRef |
|---|---|---|
| Triggers Re-renders | Yes | No |
| Purpose | State affecting UI | Persist values, DOM access |
| Value Access | State variable | .current |
| Typical Use Cases | Display data, user input | Focus elements, timers, previous values |
Important Considerations
- Direct Manipulation: Be cautious with complex objects.
- Not for Rendering: Use
useStatefor UI-bound data. - Mutability:
currentis mutable; beware multiple updates. - Persistence: Ref persists for component lifetime.
Example: Tracking Render Count
import React, { useRef } from 'react';
function RenderCounter() {
const renderCount = useRef(0);
renderCount.current++;
return Rendered {renderCount.current} times.
;
}
This shows useRef tracking renders without causing re-render loops.