vendredi 25 septembre 2026

À propos

Contact

Blocs Gutenberg

createReduxStore : un store @wordpress/data pour un bloc complexe

Quand les stores natifs ne suffisent plus, créer et enregistrer son propre store avec createReduxStore, actions, sélecteurs et resolvers, pour un bloc riche en données.

Par Clément Hadrot • 1 juin 2022 • 4 min de lecture • Aucun commentaire
createReduxStore : un store @wordpress/data pour un bloc complexe

Un bloc « comparateur de forfaits », décliné en plusieurs instances sur la même page, qui doivent toutes partager un même panier de comparaison sans qu’aucune ne connaisse directement les autres : ce genre de besoin dépasse ce que useState local ou même les stores natifs de WordPress peuvent raisonnablement couvrir. C’est exactement le cas d’usage pour lequel createReduxStore, du paquet @wordpress/data, a été pensé.

Quand un store personnalisé se justifie

Avant de se lancer dans la création d’un store, il vaut la peine de vérifier que le besoin dépasse réellement ce qu’un état local React (useState) ou les stores natifs (core, core/editor, core/block-editor) peuvent couvrir. Un store personnalisé devient pertinent quand plusieurs instances d’un même bloc, voire plusieurs blocs différents, doivent partager un état cohérent qui ne correspond à aucune entité déjà exposée par WordPress.

Étape 1 : définir l’état initial et le reducer

const DEFAULT_STATE = {
	forfaitsCompares: [],
};

function reducer( state = DEFAULT_STATE, action ) {
	switch ( action.type ) {
		case 'AJOUTER_FORFAIT':
			return {
				...state,
				forfaitsCompares: [ ...state.forfaitsCompares, action.forfaitId ],
			};
		case 'RETIRER_FORFAIT':
			return {
				...state,
				forfaitsCompares: state.forfaitsCompares.filter(
					( id ) => id !== action.forfaitId
				),
			};
		default:
			return state;
	}
}

Étape 2 : actions et sélecteurs

L'essentiel à retenir : Un store personnalisé se justifie quand plusieurs blocs partagent un même état ; Les resolvers gèrent le chargement asynchrone sans code manuel dans le composant ; register() rend le store disponible à useSelect comme n'importe quel store natif
const actions = {
	ajouterForfait( forfaitId ) {
		return { type: 'AJOUTER_FORFAIT', forfaitId };
	},
	retirerForfait( forfaitId ) {
		return { type: 'RETIRER_FORFAIT', forfaitId };
	},
};

const selectors = {
	getForfaitsCompares( state ) {
		return state.forfaitsCompares;
	},
};

Les actions restent de simples fonctions qui renvoient un objet décrivant l’événement survenu, exactement comme dans Redux classique. Les sélecteurs, eux, ne font que lire l’état, sans jamais le modifier directement.

Étape 3 : createReduxStore et register

import { createReduxStore, register } from '@wordpress/data';

const STORE_NAME = 'mon-projet/comparateur';

const store = createReduxStore( STORE_NAME, {
	reducer,
	actions,
	selectors,
} );

register( store );

Une fois register appelé, ce store devient disponible exactement comme n’importe quel store natif, via useSelect et useDispatch, depuis n’importe quel bloc du site :

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

const forfaits = useSelect(
	( select ) => select( STORE_NAME ).getForfaitsCompares(),
	[]
);
const { ajouterForfait } = useDispatch( STORE_NAME );

Étape 4 : des resolvers pour le chargement asynchrone

Si l’état initial doit être peuplé depuis une requête REST plutôt que de démarrer vide, un resolver associé à un sélecteur déclenche automatiquement le chargement dès que ce sélecteur est appelé pour la première fois, sans code manuel dans le composant :

import apiFetch from '@wordpress/api-fetch';

const resolvers = {
	*getForfaitsCompares() {
		const forfaits = yield apiFetch( { path: '/mon-projet/v1/comparateur' } );
		return actions.hydraterForfaits( forfaits );
	},
};

Cette syntaxe en générateur permet d’écrire du code asynchrone qui ressemble à du code synchrone, sans manipuler directement de promesses dans le composant React qui consomme le store.

Les limites à connaître

  • Un store personnalisé ajoute une complexité réelle : il ne se justifie pas pour un état qui reste local à une seule instance de bloc.
  • L’état d’un store @wordpress/data n’est pas persisté automatiquement entre deux rechargements de page, contrairement à un stockage local du navigateur.
  • Un store mal nommé (sans espace de noms propre à l’extension) risque une collision avec un autre store enregistré sur le même site.

Sur un projet avec un seul bloc concerné, un état local suffit presque toujours ; le passage à un store dédié se justifie surtout à partir du moment où deux blocs distincts doivent réellement se synchroniser.

En résumé

createReduxStore ouvre la voie à des blocs bien plus riches en données, capables de coordonner leur état à travers toute une page, au prix d’un peu plus de code de mise en place. Cette option reste réservée aux cas où les stores natifs de WordPress, déjà couverts par ailleurs, ne suffisent réellement plus.

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