Ch. 3 · React

React UseCallback and Captured Values

React UseCallback and Captured Values. Learn the reasoning, a practical example, common mistakes and an interview exercise.

~2 min readintermediateupdated Oct 3, 2026

UseCallback preserves a function reference between dependency changes; it does not stop the function from executing. Dependencies determine which captured values it observes.

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: A save callback reading documentId must update when that ID changes. 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: List captured values

A save callback reading documentId must refer to the currently selected document. Identify every other reactive value it reads.

Step 2: Set honest dependencies

Use documentId as a dependency. An empty dependency array keeps the old target and can save to the wrong document.

Step 3: Remove unnecessary captures

Use functional updates for state derived solely from previous state. This removes that capture without omitting other required dependencies.

Worked scenario

A save callback reading documentId must update when that ID changes.

const addTag = useCallback(tag => {
  setTags(previous => [...previous, tag]);
}, []);
const save = useCallback(() => saveDocument(documentId), [documentId]);
JSX

SetTags is a stable React setter. SaveDocument is assumed to be a stable imported adapter; if it is a reactive prop, include it as a dependency too.

Common mistake

An empty dependency list can preserve an obsolete document target.

Verify the behavior

Switch documents and invoke save. Verify the new ID reaches the adapter, and test consecutive tag additions without losing an earlier update.

Interview exercise

Avoid capturing state unnecessarily.

Answer and reasoning

Use a functional state updater when the callback only derives new state from previous state; keep other reactive dependencies explicit.

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