Ch. 3 · React

React Refs Versus State for Mutable Values

React Refs Versus State for Mutable Values. Learn the reasoning, a practical example, common mistakes and an interview exercise.

~2 min readbeginnerupdated Oct 3, 2026

Refs retain values without scheduling rendering. State belongs to visible UI; refs fit imperative handles and bookkeeping that should not determine displayed output.

Before you start

You should know how a function component renders JSX, receives props and handles events. Follow the value through render, interaction and the next render. Small snippets below belong inside an existing React application unless they are explicitly shown as complete components.

The practical goal is to reason through this situation: Store a timer handle in a ref, but store visible elapsed seconds in state. Read the walkthrough first, then try the interview exercise before opening its answer. The important part is explaining the decision and its consequences, rather than remembering a definition alone.

Step-by-step walkthrough

Step 1: Separate display and bookkeeping

Elapsed seconds affect visible output; an interval handle exists only so the timer can be stopped.

Step 2: Use the matching storage

Keep seconds in state and the handle in a ref. Updating the ref preserves information without requesting a render.

Step 3: Own timer cleanup

Stop an existing timer before starting another and clear it when the component unmounts. Refs do not clean resources automatically.

Worked scenario

Store a timer handle in a ref, but store visible elapsed seconds in state.

const [seconds, setSeconds] = useState(0);
const timer = useRef(null);
function start() {
  if (timer.current !== null) return;
  timer.current = setInterval(() => setSeconds(s => s + 1), 1000);
}
function stop() {
  clearInterval(timer.current);
  timer.current = null;
}
useEffect(() => () => clearInterval(timer.current), []);
JSX

Import the three hooks from React. Seconds trigger rendering; the handle only supports cancellation. The guard prevents duplicate intervals.

Common mistake

Mutating ref.current will not refresh text rendered from it.

Verify the behavior

Start twice, stop, restart and unmount. Verify a single increment per tick and no active timer after unmounting.

Interview exercise

Where should a selected tab live?

Answer and reasoning

In state or an external reactive store, because changing the selection must update the rendered interface.

Continue learning

Compare the scenario with the React interview questions and test your understanding with the React MCQs. For terminology and implementation details, consult the reference material.

More in React

read ✓React · hard

React Context Splitting for Performance

Stop a single context value from re-rendering every consumer by splitting state and dispatch and memoizing the provider value.

~2 min readread →
read ✓React · mid

React lazy Loading and Code Splitting

Split bundles with lazy and Suspense, work with default exports, and place boundaries so a chunk loads only when needed.

~2 min readread →
esc