Refs in React
Refs provide direct access to DOM nodes and mutable values. This lesson consolidates ref patterns: useRef, passing refs to children with forwardRef, and imperative handles for component APIs.
Ref Types in React Object refs from useRef attach via ref={myRef}. Callback refs ref={node => ...} run on mount/unmount — useful for measurements and dynamic attachment.
React 19 allows passing ref as a regular prop on function components in many cases, reducing forwardRef boilerplate.
const inputRef = useRef(null);
inputRef.current?.focus();
// forwardRef for wrapper components
const TextInput = forwardRef(function TextInput(props, ref) {
return <input ref={ref} {...props} />;
}); Parent focuses child input via ref passed through forwardRef.
Ref APIs useRef(initial) // object ref
ref={el => { ... }} // callback ref
forwardRef(Component) // pass ref through wrapper
useImperativeHandle(ref, fn) // custom imperative API Do not read/write refs during render for UI logic. useImperativeHandle exposes limited methods to parents. Callback refs fire with null on unmount. Refs avoid re-renders unlike state. Ref Pattern Reference Choose the right ref approach.
Pattern Use When useRef DOM focus, timers, mutable values forwardRef Library wrapper components Callback ref Measure DOM on mount useImperativeHandle Expose scroll/play API ref as prop (R19) Simpler ref passing
useImperativeHandle Expose controlled imperative API — scrollToBottom(), focus() — without leaking full DOM node.
useImperativeHandle(ref, () => ({
focus: () => inputRef.current?.focus(),
})); Refs vs State Decision If UI should update when value changes, use state. If value is needed for DOM/integration without re-render, use ref.
Common Mistakes Using refs to store data that should trigger renders. Overusing imperative APIs instead of declarative props. Forgetting forwardRef on reusable input components. Reading ref.current during render. Key Takeaways Refs access DOM and hold mutable non-render values. forwardRef passes refs through wrapper components. useImperativeHandle limits exposed imperative surface. React 19 simplifies ref as prop in many cases.
Pro Tip
Prefer declarative props over imperative ref methods unless integrating non-React libraries requires it.
React Portals Go to next item