Chapter 2 of 4
Reaching into the DOM
Attaching a ref to an element, and the small number of jobs that justify it.
Pass a ref object to an element's ref attribute and React sets current to the DOM node after the commit.
function SearchBox() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
}What DOM refs are for
Refs are an escape hatch. Use them for things the declarative model genuinely cannot express.
- Focus, selection and blur:
element.focus(),element.select(). - Scrolling:
element.scrollIntoView(). - Measuring:
element.getBoundingClientRect(). - Playing media:
video.play(),audio.pause(). - Handing a node to a canvas or charting library.
Callback refs
A ref can also be a function. React calls it with the node when it mounts and with null when it unmounts, which is useful when you need to react to the node appearing.
function Measured() {
const [height, setHeight] = useState(0);
const measure = useCallback((node) => {
if (node) setHeight(node.getBoundingClientRect().height);
}, []);
return <div ref={measure}>Content</div>;
}A list of refs
function Rows({ items }) {
const rowRefs = useRef(new Map());
function scrollTo(id) {
rowRefs.current.get(id)?.scrollIntoView({ behavior: "smooth" });
}
return items.map((item) => (
<li key={item.id} ref={(node) => {
if (node) rowRefs.current.set(item.id, node);
else rowRefs.current.delete(item.id);
}}>
{item.name}
</li>
));
}