访问Redux reducer中的其他州部分

时间:2016-01-06 14:22:24

标签: reactjs redux

我正在使用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不再等于state.data,我在此处要做的是将state.originalData标记设置为true。但是,使用combineReducers,我无法访问changed减速器内的状态的这些部分。

最常用的方法是什么?

1 个答案:

答案 0 :(得分:5)

米歇尔是对的,要想在传统的流量方面进行扩展,将减速器视为商店,你只需将商店中的一个称为“数据”而另一个称为“已更改” - 这不是语义上的,并且表明您可能对如何他们被使用了。

您的changed reducer应该返回未修改的状态,或者,如果某个操作被感兴趣,则返回 next 状态。它不是要弄清楚你的商店是否发生变化 - 这就是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时,将调用所有缩减器,以便他们有机会在每个缩减器键下修改状态(并返回一个新对象)。每个reducer只能访问它自己的状态。因此,在changed缩减器中,您无法像这样检查整个对象的整体对象。

但是,您可以在订阅中检查对象是否相同(此处针对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/