Access to other parts of the state in Redux gearbox

I am using Redux and would like to set the flag in state if the user has changed the data.

First, I moisten my store with some data from the server:

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

Then I have several gearboxes:

 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 }) 

What I would like to do here is set the changed flag to true if state.data no longer equal to state.originalData . However, using combReducers, I cannot access these parts of the state inside my changed reducer.

What is the most idiomatic way to do this?

+7
reactjs redux
source share
1 answer

Michelle is right, to expand it in a traditional weather vane, think of the gearbox as a store, you just called one of your “data” of your stores, and the other “changed” - this is not semantic and shows that you are probably confused about how are they used.

Your changed gear must either return an unmodified state, or if an action was taken that interests it, return the next state. This is not to find out if your store has changed - what to subscribe .

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

When you call combineReducers , it will call each reducer once with the @@redux/INIT action - but does not treat this as internal. It is important to understand that under each gearbox key, the state is initialized. In your case, you initialized data an empty object, changed to false and originalData to an empty object.

Then, when you called createStore , you said: "Update the repositories" data "and" originalData "with this initial state from the server." So, now the state of the storages "data" and "serverData" is {toggle: true} .

At this moment, both objects are the same.

Subsequently, when you call store.dispatch , all your reducers will be called so that they have the opportunity to change state (and return a new object) for each reducer key . Each gearbox has access only to its own state. Therefore, in your changed gearbox, you cannot check the general object equivalent of your entire state.

However, you can check the equality of objects in the subscription (mixed ES5 / 6 here for 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 }); 

The output of console.log should be:

 on load equal? true on change equal? false 

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

+6
source share

All Articles