Comment conserver votre boutique Redux –
Redux simplifie la gestion des états dans les applications complexes. Comme le magasin Redux contient l’état complet de votre application, sa persistance vous permet d’enregistrer et de restaurer la session de l’utilisateur.
Sommaire
Création de votre boutique
Nous supposerons que vous connaissez les principes de base de Redux.
Pour ce tutoriel, nous utiliserons un magasin barebones avec un réducteur naïf.
import {createStore} from "redux"; const state = {authenticated: false}; const reducer = (state, action) => ({...state, ...action}); const store = createStore(reducer, state);
Cet exemple trivial prépare le terrain pour un magasin Redux qui peut savoir si nous sommes connectés. La plupart des utilisateurs s’attendront à rester connectés lorsqu’ils reviendront à votre application. Pour le moment, l’état est créé à nouveau chaque fois que l’application se charge, de sorte que les utilisateurs ne restent authentifiés que dans la session en cours.
Ajout de Redux Persist
Redux Persist est une bibliothèque populaire qui vous permet d’ajouter de la persistance au magasin. La bibliothèque enregistrera automatiquement le magasin à chaque mise à jour de l’état. Vous n’avez pas besoin d’écrire de code de persistance dans vos actions ou réducteurs.
Commencez par installer Redux Persist à l’aide de npm:
npm install redux-persist
Vous devez maintenant connecter la bibliothèque à votre boutique. Enveloppez votre réducteur de racine à l’aide de Redux Persist persistReducer
fonction. Cela permet à Redux Persist d’inspecter les actions que vous envoyez à votre boutique. Vous devrez également appeler persistStore()
pour commencer la persistance.
import {createStore} from "redux"; import {persistStore, persistReducer} from "redux-persist"; import storage from "redux-persist/lib/storage"; const state = {authenticated: false}; const reducer = (state, action) => ({...state, ...action}); const persistConfig = { key: "root", storage }; const persistedReducer = persistReducer(persistConfig, reducer); const store = createStore(persistedReducer, state); const persistor = persistStore(store);
Cette configuration est maintenant prête à être utilisée. Avec seulement quelques lignes de code, nous nous sommes assurés que tous les changements d’état de Redux seront persistants automatiquement. Les utilisateurs cesseront de se déconnecter chaque fois qu’ils rechargeront votre application.
Notre réducteur est amélioré par persistReducer()
pour inclure le support de persistance. Ce réducteur nouvellement emballé est ensuite passé à createStore()
au lieu de l’original. Pour terminer, persistStore()
est appelée, en passant l’instance de magasin, pour activer la persistance.
Configurer Redux Persist
Le persistReducer()
function accepte un objet de configuration comme premier paramètre. Vous devez spécifier le key
et storage
Propriétés.
key
définit le nom de la propriété de niveau supérieur dans l’objet persistant. L’état de votre boutique sera enregistré comme valeur de cette propriété.
storage
définit le moteur de stockage à utiliser. Redux Persist prend en charge plusieurs backends de stockage différents en fonction de l’environnement. Pour une utilisation Web, le localStorage
et sessionStorage
Les API sont à la fois prises en charge ainsi que les cookies de base. Des options sont également disponibles pour React Native, Node.js, Electron et plusieurs autres plates-formes.
Vous définissez le moteur de stockage à utiliser en l’important depuis son package. Son principal objet d’implémentation d’API doit alors être passé en tant que storage
option pour Redux Persist.
Vous pouvez implémenter votre propre moteur de stockage pour utiliser un mécanisme de persistance personnalisé. Créer un objet avec setItem()
, getItem()
et removeItem()
méthodes. Redux Persist est asynchrone, donc chaque méthode doit renvoyer une promesse qui se résout lorsque l’opération est terminée.
L’objet Persistor
Le persistor
objet retourné de persistStore()
calls a quelques méthodes utilitaires pour vous permettre de gérer la persistance.
Vous pouvez suspendre et reprendre la persistance à l’aide du pause()
et resume()
méthodes respectivement. Vous pouvez forcer une écriture immédiate dans le moteur de stockage avec flush()
. Cela peut être utile si vous devez garantir que votre état est conservé après une opération particulière.
Vous pouvez purger toutes les données persistantes du moteur de stockage à l’aide de .purge()
. Dans la plupart des cas, cela doit être évité – vous devez utiliser une action Redux pour effacer votre magasin, qui se propagerait alors automatiquement aux données persistantes.
Réconciliation d’État
Redux Persist prend en charge trois façons différentes d’hydrater votre magasin à partir d’un état persistant. L’hydratation se produit automatiquement lorsque vous appelez persistStore()
et les données existantes se trouvent dans le moteur de stockage. Redux Persist doit injecter ces données initiales dans votre magasin.
La stratégie par défaut consiste à fusionner des objets jusqu’à un niveau de profondeur. Les objets imbriqués ne seront pas fusionnés – la modification entrante écrasera tout ce qui se trouve déjà dans votre état.
- État persistant:
{"demo": {"foo": "bar"}}
- État en magasin:
{"demo": {"example": test"}}
- Magasin hydraté résultant:
{"demo": {"foo": "bar"}}
Vous pouvez éventuellement passer à la fusion d’objets jusqu’à des niveaux profonds. Importez le nouveau réconciliateur d’état et ajoutez-le à la configuration de votre boutique:
// usual imports omitted import autoMergeLevel2 from "redux-persist/lib/stateReconciler/autoMergeLevel2"; const persistConfig = { key: "root", storage, stateReconciler: autoMergeLevel2 }; // store configuration omitted
Voici ce que le résultat de autoMergeLevel2
serait lors de l’hydratation de l’exemple ci-dessus:
- État persistant:
{"demo": {"foo": "bar"}}
- État en magasin:
{"demo": {"example": test"}}
- Magasin hydraté résultant:
{"demo": {"foo": "bar", "example": "test"}}
Les valeurs du demo
les propriétés des deux sources sont combinées dans l’hydratation.
Utilisez le hardSet
réconciliateur si vous souhaitez désactiver complètement la fusion. Cela remplacera l’état du magasin par le contenu du moteur de stockage. Ceci est souvent indésirable car cela complique les migrations – si vous ajoutez une nouvelle propriété initiale à votre état, elle ne sera pas définie pour les utilisateurs existants dès que leur session s’hydratera.
Migrer votre état
En ce qui concerne les migrations, Redux Persist a un support intégré pour la mise à niveau de l’état persistant vers une nouvelle version. Parfois, vous pouvez remplacer les propriétés par des alternatives plus récentes. Vous devez vous assurer que les utilisateurs existants n’auront pas à réinitialiser votre application pour continuer à l’utiliser.
Les migrations sont configurées à l’aide du migrate
clé de configuration. L’approche la plus simple consiste à transmettre une fonction qui prend l’état comme paramètre et renvoie l’état migré. Vous devez également définir le version
clé de configuration afin que Redux Persist puisse identifier quand des migrations sont nécessaires. Chaque fois que le version
change, votre fonction de migration sera appelée.
const persistConfig = { key: "root", storage, version: 1, migrate: (state) => ({...state, oldProp: undefined, newProp: "foobar"}); };
Comme alternative à l’approche fonctionnelle, vous pouvez transmettre un objet qui permet de créer des fonctions de migration individuelles pour chaque étape de version. Cela doit être transmis au createMigrate()
avant d’être transféré à la configuration de Redux Persist.
// other imports omitted import {createMigrate} from "redux-persist"; const migrations = { 1: state => ({...state, extraProp: true}), 2: state => ({...state, extraProp: undefined, extraPropNew: true}) }; const persistConfig = { key: "root", storage, version: 2, migrate: createMigrate(migrations) }
Dans cet exemple, nous initialisons le magasin en tant que version 2. Si l’état existait déjà sur l’appareil de l’utilisateur en tant que version 0, les deux migrations seraient exécutées. Si l’utilisateur était actuellement sur la version 1, seule la dernière migration s’exécuterait.
Appliquer des transformations
Un dernier point à mentionner est que Redux Persist prend en charge l’utilisation de fonctions de «transformation». Ceux-ci sont ajoutés à votre configuration et vous permettent de manipuler les données enregistrées ou restaurées.
La documentation de la bibliothèque répertorie plusieurs transformations courantes que vous pouvez utiliser. Ceux-ci vous permettent de compresser, chiffrer ou expirer automatiquement votre état persistant, sans avoir à implémenter vous-même une logique au niveau de l’application.
Les transformations sont spécifiées sous forme de tableau dans votre objet de configuration. Ils sont exécutés dans l’ordre indiqué.
const persistStore = { key: "root", storage, transforms: [MyTransformer] };
Pour écrire votre propre transformateur, utilisez le createTransform()
fonction. Ceci est passé deux fonctions et un objet de configuration:
import {createTransform} from "redux-persist"; const MyTransformer = createTransform( (inboundState, key) => ({...inboundState, b64: btoa(inboundState.b64)}), (outboundState, key) => ({...outboundState, b64: atob(outboundState.b64)}), {} );
Dans cet exemple, nous stockons le b64
propriété de notre état comme sa valeur encodée en Base64. Lorsque les données sont conservées dans le stockage (outboundState
), la valeur est encodée. Il est décodé lorsque l’état persistant est en cours d’hydratation (inboundState
).
L’objet de configuration peut être utilisé pour définir un whitelist
et blacklist
des noms de réducteurs. Le transformateur ne serait alors utilisé qu’avec des réducteurs répondant à ces contraintes.
Conclusion
Redux Persist est une bibliothèque puissante avec une interface simple. Vous pouvez configurer la persistance automatique de votre boutique Redux en seulement quelques lignes de code. Les utilisateurs et les développeurs seront reconnaissants pour sa commodité.