Chapter 1 of 4
What a Ref Is
A box React keeps for you, and how it differs from state.
useRef returns an object with a single current property. React hands you the same object on every render, and changing current does not trigger a re-render.
import { useRef } from "react";
function Timer() {
const intervalId = useRef(null);
function start() {
intervalId.current = setInterval(tick, 1000);
}
function stop() {
clearInterval(intervalId.current);
intervalId.current = null;
}
}Ref versus state
- State is for values the UI displays. Changing it re-renders.
- Ref is for values the UI does not display. Changing it does not re-render.
- State updates are asynchronous; a ref changes the moment you assign to it.
- State must be treated as immutable; a ref is meant to be mutated.
// Displayed on screen -> state
const [count, setCount] = useState(0);
// Never rendered, just remembered -> ref
const renderCount = useRef(0);
renderCount.current = renderCount.current + 1;Why not a plain variable?
A local variable is recreated on every render, so it forgets. A module-level variable is shared by every instance of the component. A ref is per-instance and survives renders, which is exactly the middle ground.
function Component() {
let a = 0; // reset on every render
const b = useRef(0); // one box per component instance, kept forever
}Good uses for a ref
- Timeout and interval ids.
- The previous value of a prop, for comparison.
- A flag such as 'has this already submitted'.
- A DOM node you need to focus, measure or scroll.
- An instance of a third-party library.