The useRef hook creates a mutable reference that persists across renders.
useRef is commonly used to access DOM elements directly.
import { useRef, useEffect } from 'react';
function FocusInput() {
// Create a ref
const inputRef = useRef(null);
// Focus the input on mount
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} type="text" />;
}useRef can store any mutable value that persists between renders.
import { useRef, useEffect } from 'react';
function IntervalExample() {
// Store the interval ID
const intervalRef = useRef(null);
useEffect(() => {
// Set up the interval
intervalRef.current = setInterval(() => {
console.log('Interval triggered');
}, 1000);
// Clean up the interval
return () => {
clearInterval(intervalRef.current);
};
}, []);
return <div>Check console for interval logs</div>;
}useRef can be used to keep track of previous prop or state values.
import { useState, useEffect, useRef } from 'react';
function Counter() {
const [count, setCount] = useState(0);
// Store the previous count value
const prevCountRef = useRef();
useEffect(() => {
// Update the ref after render
prevCountRef.current = count;
});
const prevCount = prevCountRef.current;
return (
<div>
<h1>Now: {count}, before: {prevCount}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}Unlike state, updating a ref doesn't trigger a re-render.
import { useRef, useState } from 'react';
function RenderCounter() {
const [, forceRender] = useState({});
// This value persists between renders but doesn't cause re-renders
const renderCount = useRef(0);
// Increment on each render
renderCount.current += 1;
return (
<div>
<p>This component has rendered {renderCount.current} times</p>
<button onClick={() => forceRender({})}>Force render</button>
</div>
);
}