Skip to Content

Chapitre 8.7 — Les data stores (@wordpress/data)

⏱️ TL;DR@wordpress/data est un store global façon Redux qui expose toutes les données de WordPress à vos composants : les entités (posts, meta, users, taxonomies) via le store core, l’état de l’éditeur via core/editor, etc. On lit avec useSelect et on agit avec useDispatch — deux hooks qui vous seront immédiatement familiers. Pour lire/écrire une meta du post courant, le hook useEntityProp est le raccourci idéal. C’est ce qui relie vos blocs React aux données du CMS, sans écrire d’appels REST à la main.

🎯 Objectifs

  • Comprendre le modèle store/select/dispatch.
  • Lire des données avec useSelect (entités, requêtes).
  • Modifier des données avec useDispatch / useEntityProp.
  • Gérer le chargement (isResolving) et éviter les pièges.

1. Le modèle : stores, sélecteurs, actions

@wordpress/data organise l’état en stores nommés, chacun avec des sélecteurs (lecture) et des actions (écriture) :

StoreContient
coreLes entités : posts/CPT, meta, users, taxonomies, médias, réglages du site.
core/editorL’état de l’éditeur de post (post courant, statut, sauvegarde).
core/block-editorL’état des blocs (sélection, blocs, insertion).
core/noticesLes notifications (afficher un message).

💡 Pour un dev React — C’est Redux (le vrai : @wordpress/data s’en inspire directement). useSelect = useSelector, useDispatch = useDispatch. La grande différence : les données WordPress (posts, meta, users) sont déjà dans le store core, avec résolution automatique — vous demandez getEntityRecords('postType','livre'), le store fait le fetch REST pour vous et met en cache. Vous ne câblez pas d’appels API : vous sélectionnez de la donnée qui se charge toute seule.


2. Lire avec useSelect

import { useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; function useLivres() { return useSelect( ( select ) => { const query = { per_page: 20, _fields: 'id,title' }; const livres = select( coreStore ).getEntityRecords( 'postType', 'livre', query ); const isResolving = select( coreStore ).isResolving( 'getEntityRecords', [ 'postType', 'livre', query ] ); return { livres, isResolving }; }, [] ); }
  • getEntityRecords('postType', 'livre', query) : récupère une liste de livres (le store appelle /wp/v2/livre en coulisses).
  • isResolving(...) : indique si la donnée est en cours de chargement (pour afficher un Spinner).
  • Le second argument [] (dépendances) fonctionne comme pour useMemo/useEffect.

⚠️ Piège n°1 — null pendant le chargement. Un sélecteur d’entité renvoie undefined/null tant que la donnée n’est pas chargée (puis se met à jour et re-render). Gérez ce cas (if ( ! livres ) return <Spinner/>;), sinon livres.map(...) plante. C’est le pendant du « data peut être undefined » de vos hooks de fetch.


3. Lire/écrire une meta du post courant : useEntityProp

Pour les blocs qui éditent une métadonnée du post en cours d’édition (ex. le prix d’un livre depuis un bloc dans l’éditeur du livre), useEntityProp est le raccourci :

import { useEntityProp } from '@wordpress/core-data'; function ChampPrix() { const [ meta, setMeta ] = useEntityProp( 'postType', 'livre', 'meta' ); const prix = meta?.wpr_prix ?? ''; return ( <input type="number" value={ prix } onChange={ ( e ) => setMeta( { ...meta, wpr_prix: e.target.value } ) } /> ); }
  • useEntityProp retourne un couple [valeur, setter] (comme useState) relié à l’entité courante.
  • La sauvegarde se fait quand l’utilisateur enregistre le post (l’éditeur gère la persistance via la REST API).
  • Prérequis : la meta doit être enregistrée avec show_in_rest (ch. 7.4) — sinon elle n’est pas exposée au store.

⚠️ Piège n°2 — meta non exposée. Si useEntityProp('meta') ne « voit » pas votre champ, c’est que la meta n’a pas été enregistrée avec register_post_meta(..., show_in_rest => true) (ch. 7.4). Le store core ne connaît que ce que la REST API expose.


4. Agir avec useDispatch

Pour déclencher des actions (créer une notice, sauvegarder, insérer un bloc) :

import { useDispatch } from '@wordpress/data'; import { store as noticesStore } from '@wordpress/notices'; function Bouton() { const { createSuccessNotice } = useDispatch( noticesStore ); return ( <button onClick={ () => createSuccessNotice( 'Enregistré !' ) }> Enregistrer </button> ); }

useDispatch(store) renvoie les actions du store (comme dispatch lié à un slice). On l’utilise pour interagir avec l’éditeur, les notices, ou des stores custom.


5. Appels directs : @wordpress/api-fetch

Quand vous voulez appeler un endpoint custom (Partie 9) sans passer par le store d’entités :

import apiFetch from '@wordpress/api-fetch'; const data = await apiFetch( { path: '/wpr-books/v1/stats' } );

apiFetch est pré-configuré : base REST, nonce d’authentification, gestion des erreurs. C’est votre client HTTP pour les routes maison (ch. 9). Pour les entités standard, préférez le store core (cache, réactivité) ; pour de la logique custom, apiFetch.


✏️ Exercices

  1. Reliez : useSelect, useDispatch, store core — à leurs équivalents Redux.
  2. Vous voulez une liste déroulante des livres du catalogue dans votre bloc. Quel sélecteur, et comment gérer le chargement ?
  3. Pour éditer le prix d’un livre depuis un bloc placé dans l’éditeur du livre, quel hook, et quel prérequis côté PHP ?

✅ Solution

  1. useSelectuseSelector (lecture) ; useDispatchuseDispatch (actions) ; le store core ≈ un slice contenant déjà les entités WordPress (avec résolution/fetch automatique).
  2. select(coreStore).getEntityRecords('postType','livre', query) ; gérer le chargement avec isResolving(...) (afficher un Spinner) et le cas undefined/null avant que les données n’arrivent (puis re-render).
  3. useEntityProp('postType','livre','meta') (couple [meta, setMeta]) ; prérequis : la meta doit être enregistrée avec register_post_meta(..., 'show_in_rest' => true) pour être exposée au store.

🧠 Quiz de révision

1. Qu’est-ce que @wordpress/data ?

Un store global (façon Redux) exposant les données de WordPress via des sélecteurs et actions.

2. Quel hook pour lire des données ? Pour agir ?

useSelect (lecture) et useDispatch (actions).

3. Quel store contient les entités (posts, meta, users) ?

Le store core (@wordpress/core-data), avec résolution/fetch automatique.

4. Quel hook pour lire/écrire une meta du post courant ?

useEntityProp( 'postType', type, 'meta' ) (nécessite la meta exposée en REST).

5. Comment appeler un endpoint REST custom depuis un bloc ?

Avec apiFetch({ path: '/mon-plugin/v1/…' }) (nonce et base gérés automatiquement).


Chapitre suivant : Variations, transforms & styles.