2016-01-06 9 views
7

Ich verwende Redux und möchte ein Flag in den Zustand setzen, wenn der Benutzer Daten geändert hat.Zugriff auf andere Teile des Staates in Redux Reducer

Zuerst bin ich feuchtigkeitsspend meinem Speicher mit einigen Daten vom Server:

let serverData = {toggle: true} 
const store = configureStore({data: serverData, originalData: serverData}) 

ich dann ein paar Reduzierungen haben:

function data(state = {}, action) { 
    switch (action.type) { 
    case TOGGLE: 
     return { 
     ...state, 
     toggle: !state.toggle 
     } 
    default: 
     return state 
    } 
} 

function changed(state = false, action) { 
    // This doesn't work; we are actually comparing state.changed.originalData and state.changed.data 
    return isEqual(state.originalData, state.data) 
} 

const rootReducer = combineReducers({ 
    data, 
    originalData: (state={}) => state, 
    changed 
}) 

Was Ich mag würde hier tun gesetzt wird, um die changed Flag auf "True", wenn state.data nicht länger state.originalData entspricht. Mit combineReducers kann ich jedoch nicht auf diese Teile des Zustands in meinem changed Reducer zugreifen.

Was ist der idiomatische Weg, dies zu tun?

+1

Es ist schwer zu sagen, was Sie aus dem Beispiel zu tun versuchen, aber es scheint mir, als ob Sie 'combineReducers' für eine Aufgabe verwenden, die nicht dafür gedacht war. Für einen allgemeinen Kommentar zu dem Problem, überprüfen Sie https: // github.com/rackt/redux/issues/601 # issementcomment-133519377 –

+1

Danke, ich glaube nicht, dass mir das wirklich sehr hilft. Als ein Anwendungsfall für mich: Ich möchte eine Benachrichtigung "Sie haben nicht gespeicherte Änderungen" anzeigen, wenn ein Benutzer etwas auf einer Seite bearbeitet. Wenn er dann den Inhalt wieder in den ursprünglichen Zustand versetzt, sollte diese Nachricht verschwinden. Ich bemühe mich, dies mit dem Redux-Idiom zu tun, dass jeder Reduzierer ein separates Stück Staat sieht; Ich brauche einen Reduktor, um zwei verschiedene Staatsteile zu vergleichen. –

Antwort

6

Michelle hat Recht, um es in traditionellen Flux-Begriffen zu erweitern, denken Sie an einen Reducer als ein Geschäft, Sie haben gerade einen Ihrer Filialen "Daten" und eine andere "geändert" - das ist nicht semantisch und zeigt Ihnen wahrscheinlich verwirrt sind wie sie benutzt werden.

Ihre changed Minderer sollten entweder den unveränderten Zustand zurückzukehren, oder, wenn eine Aktion gemacht wurde, dass es in, geben Sie den nächsten Zustand interessiert. Es ist nicht für herauszufinden, ob Ihr Geschäft geändert wurde - das ist, was subscribe ist. einmal, mit einer Aktion von @@redux/INIT

const unsubscribe = store.subscribe(() => 
    console.log('store was changed:', store.getState()) 
) 

Wenn Sie combineReducers nennen es wird jeden Minderer nennen - aber nicht selbst mit, dass betreffen, wie es intern ist. Das Wichtige, was zu verstehen ist, ist, dass unter jeder Reduzierung der Zustand initialisiert wird. In Ihrem Fall initialisierten Sie data zu einem leeren Objekt, changed zu false und originalData zu einem leeren Objekt.

Weiter, als Sie createStore anriefen, sagten Sie "Aktualisieren Sie die 'Daten' und 'OriginalData' speichert mit diesem Anfangszustand vom Server". Der Status der Datenspeicher 'und' serverData 'ist nun gleich {toggle: true}.

An diesem Punkt sind beide Objekte identisch.

Anschließend, wenn Sie anrufen store.dispatch alle Reduzierungen so genannt werden, dass sie eine Chance Zustand zu ändern haben können (und ein neues Objekt zurück) unter jedem Minderer Schlüssel. Jeder Reducer hat nur Zugriff auf seinen eigenen Status. Deshalb können Sie in Ihrem changed Reducer nicht die gesamte Objektgleichheit Ihres gesamten Status überprüfen.

Sie können jedoch für Objektgleichheit überprüfen in der Zeichnung (gemischte ES5/6 hier für Chrome 47)

'use strict'; 

const serverData = {toggle: true}; 
const TOGGLE = 'TOGGLE'; 

function data(state, action) { 
    state = state || {}; 
    switch (action.type) { 
    case TOGGLE: 
     return Object.assign({}, state, { 
     toggle: !state.toggle 
     }) 
    default: 
     return state 
    } 
} 

function originalData(state) { 
    state = state || {}; 
    return state; 
} 

const rootReducer = Redux.combineReducers({ 
    data, 
    originalData 
}); 

const store = Redux.createStore(rootReducer, {data: serverData, originalData: serverData }); 

const unsubscribe = store.subscribe(() => 
    console.log('on change equal?', store.getState().data === store.getState().originalData) 
) 

console.log('on load equal?', store.getState().data === store.getState().originalData); 

store.dispatch({ type: TOGGLE }); 

Die console.log ausgegeben werden soll:

on load equal? true 
on change equal? false 

Fiddle: https://jsfiddle.net/ferahl/5nwfqo9k/1/

+1

Die Jungs fragen, ist klar in der Frage. Wie kann ein Reducer auf andere Zustandsdaten zugreifen? Versuchen Sie, das Problem zu lösen, aber dann versuchen Sie, die Frage zu beantworten ... "Zugriff auf andere Teile des Staates in Redux Reducer" –

Verwandte Themen