2016-02-10 5 views

Antwort

116

Reducer ist nie ein geeigneter Ort, um dies zu tun, da Reduktoren rein sein sollten und keine Nebenwirkungen haben.

würde ich empfehlen, es in einem Teilnehmer nur tun:

store.subscribe(() => { 
    // persist your state 
}) 

Vor dem Laden zu schaffen, lesen Sie diese beharrte Teile:

const persistedState = // ... 
const store = createStore(reducer, persistedState) 

Wenn Sie combineReducers() Sie werden feststellen, dass Reduzierungen DASS haven 't erhalten den Staat wird "wie normal" mit ihrem Standard-state Argument-Wert starten. Das kann ziemlich praktisch sein.

Es ist ratsam, dass Sie Ihren Abonnenten entprellen, so dass Sie nicht zu schnell auf localStorage schreiben oder Leistungsprobleme haben.

Schließlich können Sie eine Middleware erstellen, die das als Alternative kapselt, aber ich würde mit einem Abonnenten beginnen, weil es eine einfachere Lösung ist und die Arbeit gut macht.

+1

was Wenn ich nur einen Teil des Staates abonnieren möchte? ist das möglich? Ich ging etwas anders voran: 1. rette den persistenten Zustand außerhalb von redux. 2. Laden Sie den persistenten Status in react constructor (oder mit componentWillMount) mit Redux-Aktion. Ist 2 völlig in Ordnung, anstatt die persistenten Daten direkt im Laden zu laden? (was ich versuche, getrennt für SSR zu halten). Übrigens danke für Redux! Es ist genial, ich liebe es, nachdem ich mich mit meinem großen Projektcode verloren habe, jetzt ist alles wieder einfach und vorhersehbar :) –

+0

im Laden.Wenn Sie einen Rückruf erhalten, haben Sie vollen Zugriff auf die aktuellen Geschäftsdaten, so dass Sie jeden Teil, an dem Sie interessiert sind, persistieren können. –

+18

Dan Abramov hat auch ein ganzes Video darauf gemacht: https://egghead.io/lessons/javascript-redux- persisting-the-state-to-the-local-Speicher – NateW

34

In einem Wort: Middleware.

Auschecken redux-persist. Oder schreibe deine eigenen.

[UPDATE 18 Dez. 2016] Bearbeitet, um die Erwähnung von zwei ähnlichen Projekten zu entfernen, die jetzt inaktiv oder veraltet sind.

+2

In der Zwischenzeit redux-Speicher scheint auch aufgegeben zu werden. – Dani

89

Um die Lücken von Dan Abramov Antwort füllen Sie store.subscribe() wie diese verwenden:

store.subscribe(()=>{ 
    localStorage.setItem('reduxState', JSON.stringify(store.getState())) 
}) 

Vor dem Laden zu schaffen, überprüfen localStorage und analysieren unter Ihren Schlüssel wie dies jede JSON:

const persistedState = localStorage.getItem('reduxState') ? JSON.parse(localStorage.getItem('reduxState')) : {} 

Sie geben diese peristedState Konstante an Ihre createStore Methode so weiter:

const store = createStore(
    reducer, 
    persistedState, 
    /* any middleware... */ 
) 
+1

Einfach und effektiv, ohne zusätzliche Abhängigkeiten. – AxeEffect

+1

erstellen eine Middleware kann ein bisschen besser aussehen, aber ich stimme zu, dass es effektiv ist und reicht für die meisten Fälle –

+0

Gibt es eine schöne Möglichkeit, dies zu tun, wenn Sie kombinieren, und Sie wollen nur einen Speicher beibehalten? – brendangibson

0

Wenn jemand ein Problem mit dem oben genannten hat, können Sie sich selbst zu schreiben. Lass mich dir zeigen, was ich getan habe. Ignoriere saga middleware Dinge konzentrieren sich nur auf zwei Dinge localStorageMiddleware und reHydrateStore Methode. die localStorageMiddleware ziehen alle redux state und legt es in local storage und rehydrateStore ziehen alle applicationState im lokalen Speicher, falls vorhanden und legt sie in redux store

import {createStore, applyMiddleware} from 'redux' 
import createSagaMiddleware from 'redux-saga'; 
import decoristReducers from '../reducers/decorist_reducer' 

import sagas from '../sagas/sagas'; 

const sagaMiddleware = createSagaMiddleware(); 

/** 
* Add all the state in local storage 
* @param getState 
* @returns {function(*): function(*=)} 
*/ 
const localStorageMiddleware = ({getState}) => { // <--- FOCUS HERE 
    return (next) => (action) => { 
     const result = next(action); 
     localStorage.setItem('applicationState', JSON.stringify(
      getState() 
     )); 
     return result; 
    }; 
}; 


const reHydrateStore =() => { // <-- FOCUS HERE 

    if (localStorage.getItem('applicationState') !== null) { 
     return JSON.parse(localStorage.getItem('applicationState')) // re-hydrate the store 

    } 
} 


const store = createStore(
    decoristReducers, 
    reHydrateStore(),// <-- FOCUS HERE 
    applyMiddleware(
     sagaMiddleware, 
     localStorageMiddleware,// <-- FOCUS HERE 
    ) 
) 

sagaMiddleware.run(sagas); 

export default store; 
Verwandte Themen