HuntExams Academy logo
ReactIntermediate#hooks#refs

What is useRef used for?

Answer

useRef holds a mutable value in a box that survives re-renders without causing them. It is used for DOM access, storing timers or previous values, and holding non-render data.

Example

const inputRef = useRef(null);
useEffect(() => inputRef.current?.focus(), []);
return <input ref={inputRef} />;

Detailed explanation

useRef is a React Hook that stores a mutable value in an object with a single current property. Calling useRef(initialValue) returns the same object across re-renders of that component instance. React uses the initial value only when creating the ref; subsequent renders do not reset current. Unlike a state update, assigning to ref.current does not schedule a render. This makes refs useful for information that must persist but does not determine what the screen displays. A fresh component instance gets a fresh ref.

A common use is accessing a DOM element. In your example, useRef(null) creates an initially empty ref, and passing it through <input ref={inputRef} /> lets React assign the actual input node to inputRef.current during the commit phase, when it updates the DOM. The useEffect callback runs after that commit, so inputRef.current?.focus() can focus the mounted input. Optional chaining protects against a null value. React clears the DOM ref when the element is removed. Refs support imperative operations such as focusing, scrolling, measuring, and controlling media without replacing React’s normal declarative rendering approach.

Refs also store timer IDs, external library instances, and values needed by event handlers or asynchronous callbacks. For example, an interval ID can be saved in a ref so a later handler or effect cleanup can cancel it. A ref does not automatically clean up its contents: timers and subscriptions still need explicit cleanup. For previous-value tracking, an effect can copy a state or prop value into a ref after a commit. Updating the ref in that effect does not itself make the previous value appear on screen; displaying it requires a render triggered by something else.

Interviewers usually expect a clear distinction between refs, state, and local variables. Local variables are recreated when the component renders, state persists and schedules rendering when updated to a different value, and refs persist without scheduling rendering. Use state for visible counters, input values, and loading indicators. Avoid reading or writing ref.current during rendering, except for predictable initialization, because rendering should remain pure. Normally, access refs from event handlers or effects.

Key points to remember

  • useRef returns a stable object whose mutable current property persists across re-renders.
  • Changing ref.current does not trigger a re-render or notify React of a change.
  • DOM refs provide access to mounted elements for focus, scrolling, measurement, and similar operations.
  • Refs can hold timer IDs, external instances, and other data not used to render the UI.
  • Access refs in handlers or effects, and explicitly clean up resources stored in them.

Common mistakes candidates make

  • Using a ref instead of state for visible UI data and expecting mutations to update the screen.
  • Accessing a DOM ref during rendering, before React has attached the element.
  • Assuming that storing a timer or subscription in a ref automatically handles cleanup.

Likely follow-up questions

How is useRef different from useState?

Both retain information across renders, but a state setter schedules a render when the value changes, while assigning to ref.current does not. Use state when the UI must reflect changes and a ref when the value is needed only by imperative logic.

How is useRef different from createRef?

useRef preserves the same ref object across renders of a function component. createRef creates a new object on each call and is typically used to initialize refs on class component instances.

Can a ref help avoid stale values in asynchronous callbacks?

Yes, a callback can read ref.current when it executes rather than relying only on a value captured by an earlier render. You must keep that ref synchronized at an appropriate time, usually in an effect or event handler; it does not automatically track state.

Interview tip: Start with the persistence-versus-rendering distinction, explain the input-focus example, and give a timer ID as a non-DOM use case.

Related Interview Questions

1
ReactAdvanced#hooks#performance

Difference between useMemo and useCallback?

Open
2
ReactAdvanced#performance

What is React.memo?

Open
3
ReactIntermediate#hooks#context

What is useContext and when do you use it?

Open