JAVASCRIPT
Storing Mutable Values with useRef (Non-DOM)
Utilize `useRef` in React to store mutable values that persist across component renders without triggering re-renders, ideal for managing non-DOM data like timer IDs or previous states.
import React, { useState, useEffect, useRef } from 'react';
function TimerComponent() {
const [isRunning, setIsRunning] = useState(false);
const [seconds, setSeconds] = useState(0);
// Use useRef to store the interval ID without triggering re-renders
const intervalRef = useRef(null);
useEffect(() => {
if (isRunning) {
intervalRef.current = setInterval(() => {
setSeconds((prevSeconds) => prevSeconds + 1);
}, 1000);
} else {
clearInterval(intervalRef.current);
}
// Cleanup function to clear the interval on unmount or when isRunning changes to false
return () => clearInterval(intervalRef.current);
}, [isRunning]);
const handleStart = () => setIsRunning(true);
const handleStop = () => setIsRunning(false);
const handleReset = () => {
clearInterval(intervalRef.current);
setIsRunning(false);
setSeconds(0);
};
return (
<div>
<h1>Timer: {seconds}s</h1>
<button onClick={handleStart} disabled={isRunning}>
Start
</button>
<button onClick={handleStop} disabled={!isRunning}>
Stop
</button>
<button onClick={handleReset}>
Reset
</button>
<p>
`intervalRef.current` holds the timer ID, not causing re-renders when updated.
</p>
</div>
);
}
How it works: This snippet demonstrates using `useRef` to store a mutable value, specifically a `setInterval` ID, without causing the component to re-render when the `ref`'s `current` property is updated. Unlike state variables, changing a `useRef`'s value doesn't trigger a re-render, making it perfect for holding values that need to persist across renders but aren't part of the render output, such as timer IDs, event handlers that don't change, or other imperative values.