繁体   English   中英

Redux从Reducer看到其他状态

[英]Redux see other state from Reducer

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

<FilterContainer />

<UserListContainer />

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

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

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

过滤: 航行跑步

在UserList:

约翰

坦率

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

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

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

我有两个动作, SELECT_USERSELECT_FILTER

当我点击一个过滤器( SELECT_FILTER fires)时,如果该用户仍在过滤器中,我希望ui.userList.selected持久化,如果用户ui.userList.selected过滤器中,则ui.userList.selected设置为null 。

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

但是,我很难在传统的Redux方法中做到这一点。 userList reducer看到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

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

描述逻辑的好地方是动作创建者。 使用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});
  }
};

你需要另外一个动作。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM