Redux请参阅Reducer中的其他状态

Redux see other state from Reducer

本文关键字:其他 状态 请参阅 Reducer Redux      更新时间:2023-09-26

想象一个UI有两个React组件:

<FilterContainer />

<UserListContainer />

我们从服务器上取下一组用户:

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

UI看起来有点像:

过滤器:航行跑步进食

用户列表:

约翰·

Frank

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

使用combineReducers构建的我的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被选中。但如果我点击跑步,我会看到约翰和鲍勃,但他们都没有被选中。

然而,我在传统的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

Reducer应该只知道状态的一小部分。

动作创造者是描述逻辑的好地方。使用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)中调度一个操作。此操作将为您的筛选器reducer提供当前的用户数组,您可以在那里随意设置所选字段。

如果您正在筛选服务器中的用户,我想您已经有了一个类似FETCH_users_SUCCESS的操作可以用于此操作。

它应该由过滤器还原器处理。您需要将数据作为操作负载的一部分发送给用户。因此,reducer可以计算所选的用户逻辑。您应该考虑添加一个新的操作,正如@cuttals建议的那样。