Les deux exécutent des effects, mais à des moments différents par rapport au rendu du navigateur — et c'est précisément cette différence de timing qui est l'essentiel.
Les deux exécutent des effects, mais à des moments différents par rapport au rendu du navigateur — et c'est précisément cette différence de timing qui est l'essentiel.
useEffect s'exécute après que le navigateur a rendu. C'est asynchrone et non-bloquant. Utilisez-le pour presque tout (données, subscriptions, logging).useLayoutEffect s'exécute de manière synchrone après la mutation du DOM mais AVANT le rendu du navigateur. Utilisez-le lorsque vous devez lire la mise en page et modifier le DOM dans la même frame pour éviter un scintillement visible.render → DOM updated → [useLayoutEffect runs] → browser paints → [useEffect runs]
Imaginez mesurer un élément et repositionner une infobulle en fonction de sa taille. Avec useEffect, l'utilisateur verrait brièvement l'infobulle au mauvais endroit, puis elle saute :
useLayoutEffect(() => {
const { height } = ref.current.getBoundingClientRect();
setTooltipTop(-height); // applied BEFORE paint → no visible jump
}, []);
Avec useEffect, le même code s'exécute après le rendu → un scintillement d'une frame.
useLayoutEffect rend l'interface utilisateur saccadée, car le navigateur ne peut pas faire de rendu tant qu'il n'a pas terminé.Règle générale : privilégiez useEffect par défaut ; utilisez useLayoutEffect uniquement pour les mesures/mutations synchrones du DOM qui scintilleraient autrement.