Lesson 17 of 80
Same API as useEffect, one different guarantee about timing — and that one difference exists to prevent a specific, visible flicker.
11 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 2
A tooltip briefly flashes at the wrong position before snapping to the correct one, measured from a ref. Which hook fixes this, and why?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
useEffect's callback runs after the browser has painted the screen — the user might see a frame before your effect runs. useLayoutEffect's callback runs synchronously after DOM mutations, but before the browser paints — it blocks the paint until it's done.
function Tooltip({ targetRef }) {
const [position, setPosition] = useState(null);
useLayoutEffect(() => {
const rect = targetRef.current.getBoundingClientRect();
setPosition({ top: rect.bottom, left: rect.left }); // measure, then adjust, before paint
}, [targetRef]);
return position && <div style={{ position: "absolute", ...position }}>Tip!</div>;
}
If this used useEffect instead, the browser could paint the tooltip at its default (wrong) position for one frame, then snap to the measured position — a visible flicker. useLayoutEffect measures and adjusts before the user ever sees the wrong frame.
useEffect fires AFTER the browser paints — the user can see a one-frame flicker before it runs.
useLayoutEffect blocks the browser's paint. Slow work inside it delays every visual update, which is exactly the tradeoff for its timing guarantee — use it narrowly, not as a default replacement for useEffect.ref.current's measurements.useLayoutEffect logs a warning on the server — components using it need a client-only guard, or React will (correctly) flag the mismatch."You built a tooltip that flickers to the wrong position for a split second — how do you fix it?" is a concrete, real bug, and correctly diagnosing it as a paint-timing issue (not a re-render issue) is what separates knowing the two hooks exist from actually understanding why they differ.