2017-10-08 2 views
1

Ich möchte den aktuellen Zustand eines bestimmten Reducers im Sitzungsspeicher speichern, ohne ihn bei jeder Aktion explizit aufzurufen.Redux reducer - on state change

const { handleActions } = require("redux-actions"); 

// How do i make this logic run on any state change without adding it to every action? 
const onStateChange = (state) => sessionStorage.save(keys.myReducer, state); 

const myReducer = handleActions 
({ 
    [Actions.action1]: (state, action) => (
     update(state, { 
      prop1: {$set: action.payload}, 
     }) 
    ), 
    [Actions.action2]: (state, action) => (
     update(state, { 
      prop2: {$set: action.payload}, 
     }) 
    ) 
}, 
//****************INITIAL STATE*********************** 
{ 
    prop1: [], 
    prop2: [] 
} 
); 

Gibt es eine Möglichkeit, das Statusänderungsereignis für einen bestimmten Reduzierer zu erfassen?

Ich kenne store.subscribe, aber das ist für das gesamte Geschäft, ich spreche zu einer bestimmten Reduktions Änderung hört

Dank

+0

Haben Sie Bibliotheken wie [redux-localstorage] (https://github.com/elgerlambert/redux-localstorage) oder [redox-persist] (https://github.com/rt2zz/redux-persist) ausprobiert? Oder adressieren Sie einen Nischen-Anwendungsfall, den diese Bibliotheken nicht adressieren? – excalliburbd

+0

@excalliburbd - persisting der Staat ist nicht die einzige Logik, die ich auf Zustandsänderung ausführen möchte, so dass dies leider nicht das Problem löst – Daniel

Antwort

3

Leider kann man nicht bestimmte Teile Ihres Shops, weil Ihr Geschäft sehen ist eigentlich ein einziger Reducer (Mähdrescher gibt einen einzigen großen Reducer zurück). Das heißt, Sie können manuell überprüfen, ob sich der Druckminderer geändert hat, indem Sie einen Vergleich mit einem Zustandsteil durchführen.

let previousMyReducer = store.getState().myReducer; 
store.subscribe(() => { 
    const { myReducer } = store.getState(); 
    if (previousMyReducer !== myReducer) { 
    // store myReducer to sessionStorage here 
    previousMyReducer = myReducer; 
    } 
}) 
+0

Sind Sie sicher, dass ein Vergleich durch Referenz gültig ist? Reduzieren Sie (und ändern nur) die Referenzwerte der Reduzierungen, wenn sich ein Wert ändert? – Daniel

+1

Ja, es ist der Hauptvorteil der Unveränderlichkeit von Reduzierern, wenn der Reduzierer die Aktion nicht abfängt, wird die gleiche Referenz des Zustands zurückgegeben – Freez

0

Sie können redux-saga verwenden für bestimmte Aktionen zu hören und den Laden anhalten (und tun Sie Ihre anderen Logice), wenn sie abgefeuert werden. Dies scheint eine gute Wahl für Ihre Bedürfnisse zu sein.

Es ist nicht genau mit bestimmten Speicheränderungen verbunden, sondern eher mit einer Reihe von Aktionen. Ich denke jedoch, dass dieses Modell (im Gegensatz zu Zustandsänderungen auf Aktionen achten) besser für das Redux-Design geeignet ist.

Die nette Sache ist, dass Sie keinen Code außerhalb der Saga ändern müssen. Ich habe dieses zum automatischen Speichern von Formulardaten verwendet und es hat super funktioniert.

Hier ist ein Beispiel für die Einrichtung einer Saga, die auf einigen reduktiven Aktionen bestehen soll; Beachten Sie, dass es nicht darauf beschränkt ist, zu bestehen - Sie können während einer Saga alles tun, was Sie wollen.

function* autosaveSaga(apiClient) { 
    yield throttle(500, 
    reduxFormActionTypes.CHANGE, 
    saveFormValues, 
    apiClient); 

    yield takeLatest(
    reduxFormActionTypes.ARRAY_PUSH, 
    saveFormValues, 
    apiClient); 

    yield takeLatest(
    reduxFormActionTypes.ARRAY_POP, 
    saveFormValues, 
    apiClient); 
} 

Wenn Sie auf alle Aktionstypen hören wollen, oder tun benutzerdefinierte Filterung, welche Aktionen Ihre Ausdauer Code Feuer, können Sie ein Muster oder eine passende Funktion takeLatest passieren:

yield takeLatest(
    '*', 
    saveFormValues, 
    apiClient); 

Mehr auf, was Sie an take, takeLatest usw. weitergeben können, finden Sie in the docs for take.

+0

Danke, aber genau das versuche ich zu vermeiden .. (schreibt die gleichen Zeilen bei jeder Aktion) – Daniel

+0

Mein Beispiel ist nicht optimal. Aktualisiert, um zu beachten, dass Sie ein Muster verwenden oder alle Aktionen abgleichen können. – stone