Redux从Reducer看到其他状态

时间:2016-01-08 06:58:39

标签: javascript redux

想象一下带有两个React组件的UI:

<FilterContainer />

<UserListContainer />

我们从服务器中拉下一组用户:

[
  {
    name: 'John',
    enjoys: ['Sailing', 'Running']
  },
  {
    name: 'Bob',
    enjoys: ['Running', 'Eating']
  },
  {
    name: 'Frank',
    enjoys: ['Sailing', 'Eating']
  }
]

用户界面看起来有点像这样:

过滤:航行正在进行饮食

的UserList:

约翰

您可以点击过滤器或用户。为了进入这个阶段,我们点击了'Sailing'然后点击了'Frank'(也许我们在屏幕中间看到了一张漂亮的Frank照片)。

使用combineReducers构建的My Redux状态如下所示:

{
  ui: { 
    filter: {enjoys: 'Sailing'},
    userList: {selected: 'John'}
  }
  data: [user array]
}

我有两项行动,SELECT_USERSELECT_FILTER

当我点击过滤器(SELECT_FILTER触发)时,如果该用户仍在过滤器中,我希望ui.userList.selected保持不变,并且ui.userList.selected设置为null用户不在过滤器中。

因此,如果我现在点击“吃”,我会在其中看到包含Bob和 Frank 的列表,并选择Frank。但如果我点击Running,我会看到John和Bob,但都没有被选中。

然而,我在传统的Redux方法中努力做到这一点。当userList缩减器看到SELECT_FILTER操作时,它无法检查data状态以查看当前所选用户是否仍处于该过滤条件中。

这样做的正确方法是什么?

function filter(state = {enjoys: null}, action) {
  switch (action.type) {
    case SELECT_FILTER:
      return {
        ...state,
        enjoys: action.enjoys
      }
    default:
      return state
  }
}

function userList(state = {selected: null}, action) {
  switch (action.type) {
    case SELECT_USER:
      return {
        ...state,
        selected: action.name
      }
    default:
      return state
  }
}

const ui = combineReducers({
  filter,
  userList
})

let initialUsers = [
  {
    name: 'John',
    enjoys: ['Sailing', 'Running']
  },
  {
    name: 'Bob',
    enjoys: ['Running', 'Eating']
  },
  {
    name: 'Frank',
    enjoys: ['Sailing', 'Eating']
  }
]

const rootReducer = combineReducers({
  ui,
  data: (state=initialUsers) => state // in reality, loaded from server
})

export default rootReducer

3 个答案:

答案 0 :(得分:2)

减速器应该只知道一小部分状态。

描述逻辑的好地方是动作创建者。使用redux-thunk,您将能够根据全局状态做出决定。

function selectFilter(enjoys) {
  return (dispatch, getState) => {
    dispatch({type: SELECT_FILTER, enjoys});
    // if getState().ui.userList.selected exists in getState().data
    dispatch({type: SELECT_USER, name: null});
  }
};

答案 1 :(得分:1)

你需要另外采取行动。

如果您要过滤数据缩减器中的用户,则需要在其中一个组件中调度操作&#39;当您检测到用户数组已更改时,挂钩(componentWillUpdate或componentWillReceiveProps)。此操作将为您的过滤器减速器提供当前用户数组,您可以根据需要设置所选字段。

如果您正在过滤服务器中的用户,我猜您已经有一个可以用于此的动作,如FETCH_USERS_SUCCESS。

答案 2 :(得分:0)

应该由过滤器减速器处理。您需要将用户数据作为操作有效内容的一部分发送。因此,reducer可以对所选用户逻辑进行计算。您应该考虑添加新操作,如@cuttals建议的那样。