Le premier principe de la documentation Redux est:
L'état de l'ensemble de votre application est stocké dans une arborescence d'objets dans un seul magasin.
Et je pensais en fait que je comprenais bien tous les directeurs. Mais je ne sais plus ce que signifie l'application.
Si l'application ne signifie qu'une partie peu compliquée du site Web et fonctionne sur une seule page, je comprends. Mais que faire si l'application signifie tout le site Web? Dois-je utiliser LocalStorage ou cookie ou quelque chose pour conserver l'arborescence d'état? mais que faire si le navigateur ne prend pas en charge LocalStorage?
Je veux savoir comment les développeurs conservent leur arbre d'état! :)
Réponses:
Si vous souhaitez conserver votre état redux lors d'une actualisation du navigateur, il est préférable de le faire à l'aide du middleware redux. Découvrez le middleware redux-persist et redux-storage . Ils essaient tous les deux d'accomplir la même tâche de stocker votre état redux afin qu'il puisse être sauvegardé et chargé à volonté.
-
Éditer
Cela faisait un certain temps que je n'avais pas revu cette question, mais voyant que l'autre (bien que la réponse plus votée) encourage le lancement de votre propre solution, j'ai pensé que je répondrais à nouveau.
À partir de cette modification, les deux bibliothèques ont été mises à jour au cours des six derniers mois. Mon équipe utilise redux-persist en production depuis quelques années maintenant et n'a eu aucun problème.
Bien que cela puisse sembler un problème simple, vous constaterez rapidement que le déploiement de votre propre solution entraînera non seulement une charge de maintenance, mais entraînera également des bogues et des problèmes de performances. Les premiers exemples qui me viennent à l'esprit sont:
JSON.stringify
etJSON.parse
peut non seulement nuire aux performances lorsqu'il n'est pas nécessaire, mais générer des erreurs qui, lorsqu'elles ne sont pas gérées dans un morceau de code critique comme votre magasin redux, peuvent planter votre application.Pour résumer, pour 3 Ko minifiés + gzippés (au moment de cette édition) ce n'est pas un problème que je demanderais à mon équipe de se résoudre tout seul.
la source
Edit 25-août-2019
Comme indiqué dans l'un des commentaires. Le package d' origine redux-storage a été déplacé vers react-stack . Cette approche se concentre toujours sur la mise en œuvre de votre propre solution de gestion d'état.
Réponse originale
Bien que la réponse fournie était valide à un moment donné, il est important de noter que le package redux-storage d'origine a été abandonné et qu'il n'est plus maintenu ...
Maintenant, si vous ne voulez pas avoir de dépendances sur d'autres packages pour éviter des problèmes comme ceux-ci à l'avenir, il est très facile de déployer votre propre solution.
Tout ce que vous avez à faire est:
1- Créer une fonction qui retourne l'état de
localStorage
puis passe l'état à lacreateStore
fonction redux de s dans le deuxième paramètre afin d'hydrater le magasinconst store = createStore(appReducers, state);
2- Écoutez les changements d'état et à chaque fois que l'état change, enregistrez l'état dans
localStorage
store.subscribe(() => { //this is just a function that saves state to localStorage saveState(store.getState()); });
Et c'est tout ... J'utilise en fait quelque chose de similaire en production, mais au lieu d'utiliser des fonctions, j'ai écrit une classe très simple comme ci-dessous ...
class StateLoader { loadState() { try { let serializedState = localStorage.getItem("http://contoso.com:state"); if (serializedState === null) { return this.initializeState(); } return JSON.parse(serializedState); } catch (err) { return this.initializeState(); } } saveState(state) { try { let serializedState = JSON.stringify(state); localStorage.setItem("http://contoso.com:state", serializedState); } catch (err) { } } initializeState() { return { //state object } }; } }
puis lors du démarrage de votre application ...
import StateLoader from "./state.loader" const stateLoader = new StateLoader(); let store = createStore(appReducers, stateLoader.loadState()); store.subscribe(() => { stateLoader.saveState(store.getState()); });
J'espère que ça aide quelqu'un
Note de performance
Si les changements d'état sont très fréquents dans votre application, l'enregistrement trop fréquent sur le stockage local peut nuire aux performances de votre application, en particulier si le graphique d'objet d'état à sérialiser / désérialiser est volumineux. Pour ces cas, vous voudrez peut - être debounce ou accélérateur de la fonction qui permet d' économiser à l' état localStorage en utilisant
RxJs
,lodash
ou quelque chose de similaire.la source
Ceci est basé sur la réponse de Leo (qui devrait être la réponse acceptée car elle atteint le but de la question sans utiliser de bibliothèques tierces).
J'ai créé une classe Singleton qui crée un magasin Redux, le persiste en utilisant le stockage local et permet un accès simple à son magasin via un getter .
Pour l'utiliser, placez simplement l'élément Redux-Provider suivant autour de votre classe principale:
// ... Your other imports import PersistedStore from "./PersistedStore"; ReactDOM.render( <Provider store={PersistedStore.getDefaultStore().store}> <MainClass /> </Provider>, document.getElementById('root') );
et ajoutez la classe suivante à votre projet:
import { createStore } from "redux"; import rootReducer from './RootReducer' const LOCAL_STORAGE_NAME = "localData"; class PersistedStore { // Singleton property static DefaultStore = null; // Accessor to the default instance of this class static getDefaultStore() { if (PersistedStore.DefaultStore === null) { PersistedStore.DefaultStore = new PersistedStore(); } return PersistedStore.DefaultStore; } // Redux store _store = null; // When class instance is used, initialize the store constructor() { this.initStore() } // Initialization of Redux Store initStore() { this._store = createStore(rootReducer, PersistedStore.loadState()); this._store.subscribe(() => { PersistedStore.saveState(this._store.getState()); }); } // Getter to access the Redux store get store() { return this._store; } // Loading persisted state from localStorage, no need to access // this method from the outside static loadState() { try { let serializedState = localStorage.getItem(LOCAL_STORAGE_NAME); if (serializedState === null) { return PersistedStore.initialState(); } return JSON.parse(serializedState); } catch (err) { return PersistedStore.initialState(); } } // Saving persisted state to localStorage every time something // changes in the Redux Store (This happens because of the subscribe() // in the initStore-method). No need to access this method from the outside static saveState(state) { try { let serializedState = JSON.stringify(state); localStorage.setItem(LOCAL_STORAGE_NAME, serializedState); } catch (err) {} } // Return whatever you want your initial state to be static initialState() { return {}; } } export default PersistedStore;
la source