Das erste Prinzip der Redux-Dokumentation lautet:
Der Status Ihrer gesamten Anwendung wird in einem Objektbaum in einem einzelnen Speicher gespeichert.
Und ich dachte tatsächlich, dass ich alle Prinzipien gut verstehe. Aber ich bin jetzt verwirrt, was Anwendung bedeutet.
Wenn Anwendung nur einen der wenig komplizierten Teile der Website bedeutet und auf nur einer Seite funktioniert, verstehe ich. Aber was ist, wenn Anwendung ganze Website bedeutet? Sollte ich LocalStorage oder Cookie oder etwas anderes verwenden, um den Statusbaum zu behalten? Aber was ist, wenn der Browser LocalStorage nicht unterstützt?
Ich möchte wissen, wie Entwickler ihren Statusbaum behalten! :) :)
Antworten:
Wenn Sie Ihren Redux-Status während einer Browser-Aktualisierung beibehalten möchten, verwenden Sie am besten Redux-Middleware. Schauen Sie sich die Middleware für Redux-Persist und Redux-Storage an . Beide versuchen, dieselbe Aufgabe zu erfüllen, Ihren Redux-Status zu speichern, damit er nach Belieben gespeichert und geladen werden kann.
- -
Bearbeiten
Es ist einige Zeit her, seit ich diese Frage erneut aufgegriffen habe, aber da die andere (wenn auch positivere Antwort) dazu anregt, Ihre eigene Lösung zu entwickeln, dachte ich, ich würde sie erneut beantworten.
Zum Zeitpunkt dieser Bearbeitung wurden beide Bibliotheken in den letzten sechs Monaten aktualisiert. Mein Team verwendet Redux-Persist seit einigen Jahren in der Produktion und hatte keine Probleme.
Es scheint zwar ein einfaches Problem zu sein, aber Sie werden schnell feststellen, dass das Rolling Ihrer eigenen Lösung nicht nur einen Wartungsaufwand verursacht, sondern auch zu Fehlern und Leistungsproblemen führt. Die ersten Beispiele, die mir in den Sinn kommen, sind:
JSON.stringify
undJSON.parse
kann nicht nur die Leistung beeinträchtigen, wenn sie nicht benötigt wird, sondern auch Fehler auslösen, die, wenn sie in einem kritischen Code wie Ihrem Redux-Speicher nicht behandelt werden, Ihre Anwendung zum Absturz bringen können.Zusammenfassend ist dies für 3kB minimiert + gezippt (zum Zeitpunkt dieser Bearbeitung) kein Problem. Ich würde mein Team bitten, sich selbst zu lösen.
quelle
Bearbeiten 25-Aug-2019
Wie in einem der Kommentare angegeben. Das ursprüngliche Redux-Speicherpaket wurde in den React-Stack verschoben . Dieser Ansatz konzentriert sich weiterhin auf die Implementierung Ihrer eigenen Zustandsverwaltungslösung.
Ursprüngliche Antwort
Obwohl die angegebene Antwort irgendwann gültig war, ist es wichtig zu beachten, dass das ursprüngliche Redux-Speicherpaket veraltet ist und nicht mehr gewartet wird ...
Wenn Sie keine Abhängigkeiten von anderen Paketen haben möchten, um solche Probleme in Zukunft zu vermeiden, ist es sehr einfach, Ihre eigene Lösung zu entwickeln.
Alles was Sie tun müssen ist:
1- Erstellen Sie eine Funktion, die den Status von zurückgibt,
localStorage
und übergeben Sie den Status dann an diecreateStore
Redux-Funktion im zweiten Parameter, um den Speicher mit Feuchtigkeit zu versorgenconst store = createStore(appReducers, state);
2- Achten Sie auf Statusänderungen und speichern Sie den Status jedes Mal, wenn sich der Status ändert
localStorage
store.subscribe(() => { //this is just a function that saves state to localStorage saveState(store.getState()); });
Und das war's ... Ich verwende tatsächlich etwas Ähnliches in der Produktion, aber anstatt Funktionen zu verwenden, habe ich eine sehr einfache Klasse wie unten geschrieben ...
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 } }; } }
und dann beim Bootstrapping Ihrer App ...
import StateLoader from "./state.loader" const stateLoader = new StateLoader(); let store = createStore(appReducers, stateLoader.loadState()); store.subscribe(() => { stateLoader.saveState(store.getState()); });
Hoffe es hilft jemandem
Leistungshinweis
Wenn Statusänderungen in Ihrer Anwendung sehr häufig sind, kann das zu häufige Speichern im lokalen Speicher die Leistung Ihrer Anwendung beeinträchtigen, insbesondere wenn das zu serialisierende / deserialisierende Statusobjektdiagramm groß ist. In diesen Fällen möchten Sie möglicherweise die Funktion, mit der der Status in localStorage gespeichert wird
RxJs
,lodash
oder etwas Ähnliches entprellen oder drosseln .quelle
Dies basiert auf Leos Antwort (die die akzeptierte Antwort sein sollte, da sie den Zweck der Frage ohne Verwendung von Bibliotheken von Drittanbietern erfüllt).
Ich habe eine Singleton-Klasse erstellt , die einen Redux-Speicher erstellt, ihn unter Verwendung des lokalen Speichers beibehält und einen einfachen Zugriff auf den Speicher über einen Getter ermöglicht .
Um es zu verwenden, platzieren Sie einfach das folgende Redux-Provider-Element um Ihre Hauptklasse:
// ... Your other imports import PersistedStore from "./PersistedStore"; ReactDOM.render( <Provider store={PersistedStore.getDefaultStore().store}> <MainClass /> </Provider>, document.getElementById('root') );
und fügen Sie Ihrem Projekt die folgende Klasse hinzu:
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;
quelle