我正在使用Redux,如果用户修改了数据,我想在状态中设置一个标志.
首先,我使用服务器中的一些数据为我的商店补充水分:
let serverData = {toggle: true} const store = configureStore({data: serverData, originalData: serverData})
然后我有一些减速器:
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 })
我想在这里做的是将changed
标志设置为true,如果state.data
不再等于state.originalData
.但是,使用combineReducers,我无法访问我的changed
reducer 中的状态的这些部分.
最常用的方法是什么?
米歇尔是对的,要想在传统的流量方面进行扩展,将减速器视为商店,你只需将商店中的一个称为"数据",另一个称为"更改" - 这不是语义上的,并且表明你可能对它们如何被混淆感到困惑用过的.
你的changed
减速器应该返回未修改的状态,或者,如果做出它感兴趣的动作,则返回下一个状态.它不是要弄清楚你的商店是否有所改变 - 这subscribe
就是为了什么.
const unsubscribe = store.subscribe(() => console.log('store was changed:', store.getState()) )
当你打电话时,combineReducers
它会调用每个减速器一次,@@redux/INIT
但是不要把它当作内部动作.需要了解的重要一点是,在每个reducer密钥下,状态都是初始化的.在您的情况下,您初始化data
为空对象,changed
false,以及originalData
空对象.
接下来当你打电话给createStore
你时说"用服务器的初始状态更新'数据'和'originalData'商店".所以现在'data'和'serverData'存储的状态等于{toggle: true}
.
此时两个对象都是相同的.
随后当您调用store.dispatch
所有reducers时,将调用它们以便他们有机会在每个reducer键下修改状态(并返回一个新对象).每个reducer只能访问它自己的状态.因此,在您的changed
reducer中,您无法检查整个对象的整体对象是否相同.
但是,您可以在订阅中检查对象是否相等(此处针对Chrome 47的混合ES5/6)
'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 });
console.log输出应该是:
on load equal? true on change equal? false
小提琴:https://jsfiddle.net/ferahl/5nwfqo9k/1/