# « Deux niveaux de contexte imbriqués : quand le petit-enfant se perd »

> Sur un bloc à trois niveaux de profondeur, le contexte attendu n'atteignait jamais le composant final. En cause, l'ordre de déclaration et une re-fourniture intermédiaire oubliée.

- Auteur : Clément Hadrot
- Publié le : 2024-09-12
- Mis à jour le : 2024-09-12
- Catégorie : Blocs Gutenberg
- URL : https://wpmoderne.dev.wordpress-developpement.fr/blocs/deux-niveaux-contexte-imbrique-petit-enfant-perdu/

## L’essentiel

- Le contexte ne traverse pas un niveau qui ne le redéclare pas
- providesContext doit être répété à chaque étage intermédiaire
- Vérifier avec useBlockProps et l'inspecteur DOM

Le bloc « fiche produit » de la Ferme du Clos, une exploitation en vente directe, s'organise sur trois niveaux : un bloc racine `ferme/fiche-produit` qui fixe l'identifiant du produit, un bloc intermédiaire `ferme/section-prix` qui organise l'affichage du tarif, et à l'intérieur de celui-ci, un bloc `ferme/badge-promo` censé savoir si le produit racine est en promotion. Sur le papier, le contexte de bloc (`providesContext` / `usesContext`) est fait exactement pour ce genre de transmission verticale. En pratique, le badge affichait systématiquement « non défini » pour la valeur qu'il attendait.

## Symptôme : un contexte qui s'arrête en chemin

Le bloc racine déclarait correctement son contexte :

```
{
  "name": "ferme/fiche-produit",
  "providesContext": {
    "ferme/produitId": "produitId",
    "ferme/enPromotion": "enPromotion"
  }
}
```

Et le badge, tout en bas, déclarait bien qu'il consommait cette valeur :

```
{
  "name": "ferme/badge-promo",
  "usesContext": ["ferme/enPromotion"]
}
```

Entre les deux, la déclaration du bloc `ferme/section-prix` ne mentionnait ni `providesContext`, ni `usesContext`, sous prétexte qu'il n'avait lui-même besoin d'aucune de ces valeurs pour son propre rendu.

## Diagnostic : le contexte ne traverse pas, il se propage de parent direct à enfant direct

C'est là l'erreur de modèle mental la plus fréquente sur ce mécanisme : le contexte de bloc n'est pas une variable globale accessible à toute la descendance, mais une transmission de `InnerBlocks` parent vers ses enfants directs, niveau par niveau. Un bloc intermédiaire qui ne consomme pas explicitement une clé de contexte (via `usesContext`) ne la retransmet pas automatiquement à ses propres enfants, même s'il ne fait qu'englober une zone d'`InnerBlocks` sans rien afficher lui-même.

> L'essentiel à retenir : Le contexte ne traverse pas un niveau qui ne le redéclare pas ; providesContext doit être répété à chaque étage intermédiaire ; Vérifier avec useBlockProps et l'inspecteur DOM

## Le correctif : consommer puis republier explicitement

Le bloc intermédiaire doit à la fois consommer la valeur qu'il ne va pas afficher, et la republier dans son propre `providesContext` pour que ses propres enfants (le petit-enfant du bloc racine) puissent la lire à leur tour :

```
{
  "name": "ferme/section-prix",
  "usesContext": ["ferme/enPromotion"],
  "providesContext": {
    "ferme/enPromotion": "enPromotion"
  }
}
```

Côté composant d'édition du bloc intermédiaire, il faut également accepter la prop `context` même sans s'en servir directement, pour que React Blocks établisse correctement la chaîne :

```
function Edit({ context }) {
  const enPromotion = context['ferme/enPromotion'];
  // Le composant n'affiche rien de cette valeur, il la laisse simplement
  // traverser pour que providesContext dispose d'une source à republier.
  return <div {...useBlockProps()}><InnerBlocks /></div>;
}
```

## Vérifier la chaîne avec l'inspecteur DOM

Pour confirmer qu'un contexte traverse bien tous les niveaux, la méthode la plus rapide reste d'ajouter temporairement un `console.log(context)` dans chaque composant d'édition de la chaîne, plutôt que de deviner. Le contexte de bloc n'apparaît dans aucun attribut visible dans l'inspecteur DOM du navigateur : il vit uniquement dans l'arbre de composants React de l'éditeur, ce qui rend le débogage visuel impossible sans instrumentation du code.

- Chaque niveau intermédiaire doit déclarer `usesContext` pour la clé à transmettre, même s'il ne l'utilise pas lui-même.
- Chaque niveau intermédiaire doit republier la même clé dans son propre `providesContext`.
- Un `console.log` temporaire à chaque étage reste plus fiable qu'une inspection DOM pour ce type de bug.

## Ce que ce cas ne couvre pas

Le partage de contexte à un seul niveau, parent direct vers enfant direct, fonctionne sans piège particulier et a déjà été couvert ailleurs. Ce cas concerne spécifiquement la propagation à travers un niveau intermédiaire qui ne consomme pas la donnée pour son propre usage.

> Un contexte de bloc ne traverse jamais un étage muet : il faut qu'un niveau parle, même juste pour se taire et republier ce qu'il a reçu.

## Notre verdict

Ce bug a coûté à l'équipe de la Ferme du Clos une demi-journée de débogage, essentiellement parce que la documentation officielle illustre presque toujours des exemples à deux niveaux. Dès qu'un bloc s'organise sur trois niveaux ou plus, il faut systématiquement vérifier que chaque étage intermédiaire republie ce qu'il consomme, même sans usage propre de la valeur.
