Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Le voyage complet du JSX aux pixels — déclenchez un rendu et regardez chaque phase s'exécuter.
Chaque fois que React effectue un rendu, il suit un pipeline prévisible en deux phases : la Phase de Rendu et la Phase de Commit. La phase de rendu est pure et interruptible — React appelle vos composants et construit un nouvel arbre Fiber. La phase de commit est synchrone et produit des effets de bord — React applique les changements calculés au DOM réel et déclenche les effets.
Au moment de la compilation, du JSX comme <Button color='blue'>Cliquer</Button> devient React.createElement(Button, '{' color: 'blue' '}', 'Cliquer'). Cela produit un arbre d'objets simples — le DOM Virtuel.
React parcourt l'arbre Fiber en appelant chaque fonction composant (ou méthode render()). Cette phase est pure et ne produit aucun effet de bord — React peut l'interrompre et la redémarrer à tout moment en mode concurrent.
React compare la nouvelle sortie avec l'arbre Fiber précédent. Il marque chaque fiber avec un tag d'effet : Update, Placement (insertion) ou Deletion. Le résultat est une 'liste d'effets' — une liste plate de fibers avec du travail en attente.
React appelle getSnapshotBeforeUpdate() sur les composants classe et planifie les effets passifs. Cette sous-phase s'exécute avant que des mutations DOM surviennent.
React parcourt la liste d'effets et applique toutes les mutations DOM de manière synchrone : insertions, mises à jour, suppressions. Après cela, le DOM reflète la nouvelle interface.
Les callbacks useLayoutEffect s'exécutent de manière synchrone après la mutation DOM mais avant le dessin du navigateur. Ensuite le navigateur dessine. Finalement, les callbacks useEffect s'exécutent de manière asynchrone après le dessin.
Phase pure, sans effets de bord, où React appelle les composants et construit le nouvel arbre Fiber. Peut être interrompue en mode concurrent.
Phase synchrone où React applique les mutations DOM et déclenche les méthodes de cycle de vie/effets. Ne peut pas être interrompue.
Se déclenche de manière synchrone après la mutation DOM, avant le dessin du navigateur. À utiliser pour les mesures DOM. Bloque le dessin.
Se déclenche de manière asynchrone après le dessin du navigateur. Ne bloque pas le dessin — idéal pour les abonnements, les requêtes réseau et les effets de bord non visuels.
En développement, React rend les composants deux fois dans la phase de rendu pour détecter les effets de bord. Un seul commit se produit.
1function MyComponent() {2 // Fires: after every render, after browser paint (async)3 useEffect(() => {4 console.log('3. useEffect — DOM painted, async');5 return () => console.log('cleanup');6 });78 // Fires: after every render, before browser paint (sync)9 useLayoutEffect(() => {10 console.log('2. useLayoutEffect — DOM mutated, not painted');11 });1213 console.log('1. Render phase — pure, no side effects');14 return <div />;15}16// Order: Render → DOM mutation → useLayoutEffect → Paint → useEffect
Comprendre le pipeline vous aide à placer le code au bon endroit. Les mesures DOM doivent aller dans useLayoutEffect (avant le dessin). La récupération de données va dans useEffect (après le dessin, non bloquant). L'initialisation devant survenir avant le premier rendu va dans l'initialiseur useState ou useMemo. Se tromper sur ce point cause des flashs visuels, des sauts de mise en page ou des rendus manqués.
You're building a tooltip that positions itself relative to a target element. Using useEffect, the tooltip first renders at (0,0), then jumps to the correct position — causing a visible flash.
useEffect fires AFTER the browser paints. So the sequence is: Render (tooltip at 0,0) → Paint (user sees misplaced tooltip) → useEffect (measure & reposition) → Re-render → Paint (correct). The first paint shows the wrong position.
Switch to useLayoutEffect which fires AFTER DOM mutation but BEFORE paint. The sequence becomes: Render → DOM mutation → useLayoutEffect (measure & update) → Paint (correct position). The user never sees the wrong position because the browser hasn't painted yet.
Takeaway: Use useLayoutEffect for any DOM measurement or mutation that affects visual layout (tooltips, popovers, scroll position, animations). Use useEffect for everything else (data fetching, analytics, subscriptions).
You add console.log statements to debug when state changes propagate. The logs appear in an unexpected order: render logs appear before effect logs, and cleanup logs appear between them.
Without understanding the pipeline phases, developers assume effects run 'during' rendering. They place side effects in the render function body (causing bugs) or misread the log order and chase phantom timing issues.
The rendering pipeline has strict phases: Render (pure, produces VDOM) → Commit (DOM writes) → Layout Effects (sync, before paint) → Paint (browser) → Effects (async, after paint). Each console.log appears in pipeline order. Understanding this order lets you read debug output correctly and place code in the right phase.
Takeaway: The rendering pipeline is NOT a single step — it's 5 distinct phases with different timing guarantees. Most React bugs come from putting code in the wrong phase (e.g., side effects in render, DOM reads in useEffect instead of useLayoutEffect).