« Rendered more hooks than during the previous render. » Ce message, affiché dans la console au moment d’éditer un bloc, accompagne souvent un plantage complet du composant, capturé ou non par une limite d’erreur (error boundary) selon la configuration de l’éditeur. Il signale une violation d’une règle stricte de React : le nombre et l’ordre des hooks appelés doivent rester strictement identiques à chaque rendu d’un même composant.
Symptôme
Le bloc fonctionne correctement dans certains cas, puis se met soudainement à afficher ce message dès qu’une condition particulière se présente : un attribut vide, une donnée non encore chargée, une valeur d’inspecteur modifiée dans un ordre précis. Le composant peut alors disparaître entièrement du canevas, remplacé par un message d’erreur générique, sans que le code semble avoir changé depuis le dernier rendu qui fonctionnait normalement.
Diagnostic
La cause la plus fréquente tient dans un hook (useState, useEffect, useSelect…) placé après un retour anticipé dans le composant :
export default function Edit( { attributes } ) {
if ( ! attributes.identifiantSource ) {
return <p>Veuillez renseigner une source.</p>; // retour anticipé
}
// Ce hook n'est appelé que si la condition ci-dessus est fausse :
// le nombre de hooks change d'un rendu à l'autre.
const [ donnees, setDonnees ] = useState( null );
// ...
}
Tant que attributes.identifiantSource reste vide, le composant s’arrête avant d’appeler useState. Dès que la valeur est renseignée, un rendu supplémentaire ajoute cet appel de hook, que React n’attendait pas à cette place dans la séquence. React compare, à chaque rendu, la liste des hooks appelés dans leur ordre exact : toute divergence dans ce nombre ou cet ordre déclenche ce message, quelle que soit la nature du hook concerné.

Correctif
La règle des hooks de React impose de toujours les appeler au même niveau, avant toute condition ou retour anticipé, et de déplacer la logique conditionnelle à l’intérieur du corps du composant, pas autour de l’appel du hook lui-même :
export default function Edit( { attributes } ) {
const [ donnees, setDonnees ] = useState( null ); // toujours appelé en premier
if ( ! attributes.identifiantSource ) {
return <p>Veuillez renseigner une source.</p>;
}
// suite du composant, qui peut désormais utiliser « donnees »
// et « setDonnees » en toute sécurité
}
Ce réordonnancement garantit que tous les hooks du composant sont appelés à chaque rendu, dans le même ordre, indépendamment de la valeur des attributs. Le retour anticipé peut toujours exister, à condition d’être placé après la déclaration de tous les hooks, jamais avant.
Le cas plus discret d’un hook dans une boucle ou une condition
La même erreur peut survenir sous une forme moins visible : un hook appelé à l’intérieur d’une condition (if ( quelqueChose ) { useEffect( ... ); }) ou d’une boucle dont le nombre d’itérations varie d’un rendu à l’autre. Dans les deux cas, la correction suit le même principe : sortir l’appel du hook de la structure conditionnelle ou itérative, et déplacer la logique conditionnelle à l’intérieur du callback passé au hook plutôt qu’autour de son appel.
- Repérer chaque appel de hook du composant et vérifier qu’aucun ne se trouve après un
return, dans unifou dans une boucle. - Déplacer la condition à l’intérieur du corps du hook plutôt qu’autour de son appel.
- Utiliser l’extension ESLint officielle des règles de hooks React, qui détecte la plupart de ces cas avant même l’exécution du code.
Prévention
Installer et activer le plugin ESLint eslint-plugin-react-hooks, déjà inclus dans la configuration fournie par @wordpress/scripts, signale ce type d’erreur directement dans l’éditeur de code, avant même de tester le bloc dans le navigateur. Sur un projet où cette règle n’est pas encore activée dans le pipeline de vérification, l’ajouter au script de lint existant évite la quasi-totalité des occurrences de ce message en amont du développement.
En résumé
« Rendered more hooks than during the previous render » traduit presque systématiquement un hook déplacé après un retour anticipé, une condition ou une boucle. La règle à retenir reste simple : tous les hooks d’un composant s’appellent inconditionnellement, dans le même ordre, à chaque rendu, la logique variable se plaçant à l’intérieur du hook, jamais autour de son appel.