useEffect: Runs after paint (async), non-blocking. Good for: data fetching, subscriptions, logging.
1useEffect(() => { fetch("/api/data"); }, []);
useLayoutEffect: Runs after DOM mutation, before paint (sync), blocks paint. Good for: DOM measurements.
1useLayoutEffect(() => {2 const rect = ref.current.getBoundingClientRect();3 setHeight(rect.height);4}, []);
When useLayoutEffect: Measuring element size/position, preventing visual flicker, synchronizing with DOM.
Default: Use useEffect unless you need sync DOM access.