vendredi 25 septembre 2026

À propos

Contact

Blocs Gutenberg

useSelect et useDispatch : lire et modifier les données de l’éditeur

Deux hooks suffisent à connecter un bloc aux stores de Gutenberg. Voici comment ils fonctionnent réellement, et où les développeurs se trompent le plus souvent.

Par Clément Hadrot • 12 février 2020 • 5 min de lecture • Aucun commentaire
useSelect et useDispatch : lire et modifier les données de l'éditeur

Un client m’a récemment envoyé un bloc qui recevait ses données via cinq niveaux de props, avec un composant intermédiaire dont le seul rôle était de transmettre une valeur qu’il n’utilisait jamais. Le correctif tenait en une ligne : useSelect. C’est souvent le symptôme d’une méconnaissance des stores @wordpress/data, alors que Gutenberg en expose plusieurs, prêts à l’emploi, dès qu’un bloc a besoin d’informations qui ne lui appartiennent pas en propre.

Ce module de données n’est pas Redux au sens strict, mais il en reprend l’esprit : un état centralisé, des sélecteurs pour le lire, des actions pour le modifier. Deux hooks React, fournis par @wordpress/data, donnent accès à ce mécanisme depuis un composant de bloc : useSelect pour lire, useDispatch pour écrire. Comprendre leur fonctionnement interne évite bien des rendus inutiles et des bugs difficiles à reproduire.

Les stores que Gutenberg met à disposition

Trois stores reviennent dans la quasi-totalité des blocs : core/block-editor expose l’état de l’éditeur de blocs lui-même (sélection, structure de l’arbre, blocs voisins), core/editor gère le contenu de l’article en cours d’édition (statut, métadonnées, verrouillage), et core centralise les entités REST (articles, pages, types de contenu personnalisés, taxonomies). Un bloc qui veut connaître le titre de l’article courant interroge core/editor ; un bloc qui veut savoir combien de blocs sont sélectionnés interroge core/block-editor.

Chaque store expose des sélecteurs, des fonctions pures qui prennent l’état global et renvoient une valeur dérivée. Ils sont documentés au fil des versions de Gutenberg et il vaut mieux vérifier leur signature exacte plutôt que de deviner un nom par analogie.

useSelect : lire sans provoquer de rendus superflus

L'essentiel à retenir : useSelect relit le store à chaque changement ; useDispatch renvoie des actions stables ; Les deux évitent les props qui traversent trop de niveaux

useSelect prend une fonction de rappel qui reçoit select, la porte d’entrée vers n’importe quel store enregistré, et un tableau de dépendances optionnel :

import { useSelect } from '@wordpress/data';

function TitreArticle() {
	const title = useSelect( ( select ) => {
		return select( 'core/editor' ).getEditedPostAttribute( 'title' );
	}, [] );

	return <p>{ title }</p>;
}

Le hook s’abonne automatiquement aux changements du store et ne redéclenche un rendu que si la valeur retournée diffère de la précédente. C’est là que se cache le piège le plus fréquent : renvoyer un nouvel objet ou un nouveau tableau à chaque appel casse cette comparaison, car une nouvelle référence est toujours considérée comme « différente », même si son contenu est identique. Il faut renvoyer des valeurs primitives ou des références stables, quitte à composer plusieurs appels à useSelect plutôt qu’un seul retournant un objet complexe.

useDispatch : obtenir des actions, pas un état

useDispatch ne lit rien : il renvoie les créateurs d’actions d’un store, à appeler dans un gestionnaire d’événement.

import { useDispatch } from '@wordpress/data';

function BoutonTitre() {
	const { editPost } = useDispatch( 'core/editor' );

	return (
		<button onClick={ () => editPost( { title: 'Nouveau titre' } ) }>
			Renommer
		</button>
	);
}

Contrairement aux sélecteurs, les fonctions renvoyées par useDispatch sont stables entre les rendus : elles peuvent sans risque être placées dans un tableau de dépendances d’un useEffect ou d’un useCallback sans provoquer de boucle.

Deux erreurs qui reviennent en revue de code

  • Appeler useSelect à l’intérieur d’une condition ou d’une boucle : comme tout hook React, il doit s’exécuter dans le même ordre à chaque rendu.
  • Oublier le tableau de dépendances quand le sélecteur dépend d’une valeur externe (un attribut du bloc, par exemple) : le résultat reste alors figé sur sa première évaluation.
  • Multiplier les appels à select( 'core' ) avec des arguments légèrement différents sans mémoriser ces arguments, ce qui déclenche des requêtes REST en boucle lorsque l’entité n’est pas encore en cache.

Un cas d’usage concret : compter les blocs enfants

Un bloc de type « accordéon » qui doit afficher un compteur de panneaux ouverts illustre bien la complémentarité des deux hooks : useSelect lit la liste des blocs enfants via getBlockOrder du store core/block-editor, et useDispatch permet, en retour, de sélectionner un enfant particulier avec selectBlock lorsqu’on clique sur un onglet du panneau.

Sur nos projets, remplacer des props transmises sur trois ou quatre niveaux de composants par un useSelect direct au bon endroit réduit systématiquement la taille du fichier de bloc principal, souvent de moitié.

En résumé

Ces deux hooks suffisent à connecter n’importe quel bloc à l’état global de l’éditeur sans créer de store personnalisé, ce qui reste l’option la plus simple tant que les données manipulées appartiennent déjà à un store existant. Dès qu’un bloc a besoin d’un état qui n’existe dans aucun store natif, en revanche, il faut passer à la création d’un store dédié — un sujet qui mérite un article à part entière.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi