React: From Components to Production · State, Events and Effects
Refs and the DOM
Hold mutable values and access DOM nodes with useRef.
useRef returns a mutable object whose .current persists across renders without causing re-renders. Use refs for DOM access (focus, measure, scroll), timers and other values not needed for rendering. Attach to elements with the ref attribute; in React 19, function components accept ref as a regular prop, and ref callbacks can return a cleanup function.
import { useRef } from "react";
export function SearchField({ ref, ...props }: React.ComponentProps<"input">) {
return <input type="search" ref={ref} {...props} />;
}
export function SearchBar() {
const inputRef = useRef<HTMLInputElement>(null);
const timer = useRef<number | undefined>(undefined);
function onChange(value: string) {
window.clearTimeout(timer.current);
timer.current = window.setTimeout(() => search(value), 300); // debounce
}
return (
<>
<SearchField ref={inputRef} onChange={(e) => onChange(e.target.value)} />
<button onClick={() => inputRef.current?.focus()}>Focus search</button>
</>
);
}
Common pitfalls
- Reading or writing
ref.currentduring render (except lazy initialization). - Using refs to store data that should trigger UI updates.
- Manipulating DOM managed by React (removing nodes React renders).
Key points
- Refs persist without re-rendering
- Use for DOM access and timers
- ref is a prop in React 19
Further reading: react.dev: Referencing values with refs
Practice questions
What's the difference between state and a ref?
Answer
Updating state triggers a re-render and the value is a snapshot per render; updating a ref doesn't re-render and .current is mutable. Use refs for values not shown in the UI.
How do you pass a ref to a custom input component in React 19?
Answer
Accept ref as a normal prop and pass it to the underlying <input>. forwardRef is no longer required for function components.
Open in the app to mark lessons complete, take notes and track your progress.