La réconciliation est le processus algorithmique par lequel React met à jour l’interface utilisateur.
Elle consiste à comparer l’arbre d’éléments newly généré (après un changement d’état) avec l’arbre précédent, afin de déterminer le nombre minimal de modifications à appliquer au DOM réel.
Caractéristiques techniques
| Propriété | Description |
|---|---|
| Déclencheur | Un changement de state ou de props dans un composant. |
| Mécanisme | Algorithme de « Diffing » (comparaison de différences). |
| Complexité | Heuristique en O(n) (linéaire), optimisée pour la performance. |
| Objectif | Minimiser les manipulations coûteuses du DOM réel. |
| Résultat | Une mise à jour partielle et ciblée du navigateur. |
Comment ça marche ? (Le Flux)
- Render : Un changement d’état survient → React exécute les composants → Génère un nouvel arbre d’éléments.
- Diffing : React compare le nouvel arbre avec l’ancien arbre (mémoire).
- Calcul : Il identifie les nœuds changés, ajoutés ou supprimés.
- Commit : Il applique uniquement ces différences au DOM réel.
DOM Réel : un mur de briques physique (coûteux à modifier).
Virtual DOM : un plan sur papier (rapide à dessiner/modifier).
Réconciliation : l’architecte compare l’ancien plan et le nouveau plan, puis donne aux ouvriers uniquement la liste des briques à déplacer, au lieu de reconstruire tout le mur.
Exemple concret
function Compteur() {
const [count, setCount] = useState(0);
return (
<div>
<p>Compteur : {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
Scénario : L’utilisateur clique sur le bouton
- Avant : Le DOM affiche
<p>Compteur : 0</p>. - Action :
setCount(1)déclenche un re-rendu. - Réconciliation :
- React compare l’ancien
<p>et le nouveau<p>. - Il voit que la balise
<div>et<button>n’ont pas changé → Ignorés. - Il voit que le texte dans
<p>a changé (0→1) → Marqué pour mise à jour.
- React compare l’ancien
- Résultat : React ne touche qu’au nœud texte dans le navigateur. Le reste du DOM reste intact.
Rôle crucial des keys dans les listes dynamiques
Lors de la réconciliation de listes d’éléments, React utilise la prop key pour identifier quel élément a changé, été ajouté ou supprimé.
// SANS KEY (Réconciliation inefficace)
// React peut recréer tous les éléments du DOM si l'ordre change
{items.map(item => <li>{item}</li>)}
// AVEC KEY (Réconciliation optimisée)
// React suit chaque élément individuellement grâce à l'ID unique
{items.map(item => <li key={item.id}>{item}</li>)}
Sans key, React se base sur l’index. Si vous insérez un élément au début, tous les indices changent, et React peut penser que toute la liste a changé, détruisant potentiellement l’état interne des composants enfants.
La règle des keys s’applique uniquement aux listes d’éléments (quand tu utilises .map() pour générer plusieurs éléments similaires).
Dans l’exemple précédent la structure est statique. React sait que :
- Le premier enfant du
<div>est toujours le<p>. - Le deuxième enfant du
<div>est toujours le<button>.
Il n’y a pas d’ambiguïté, donc React n’a pas besoin de key pour les identifier. Il se base sur leur position dans l’arbre.
La key devient nécessaire si tu utilises ton composant Compteur plusieurs fois dans une liste.
Imaginez que tu vous voulez afficher 3 compteurs :
function App() {
const compteurs = [1, 2, 3];
return (
<div>
{/* SANS KEY (React va afficher un warning dans la console) */}
{compteurs.map((id) => (
<Compteur />
))}
{/* AVEC KEY (Chaque instance est identifiée uniquement) */}
{compteurs.map((id) => (
<Compteur key={id} />
))}
</div>
);
}