首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Redux:重用reducer来更新多个状态属性

Redux:重用reducer来更新多个状态属性
EN

Stack Overflow用户
提问于 2018-09-21 11:04:53
回答 2查看 1.3K关注 0票数 2

也许这只是我的Redux知识中缺少的一部分信息,但即使在搜索了几个小时后,我仍然不知道如何创建一个可重用的reducer来更新许多状态属性。

比方说,我创建了一个简单的组件MySwitch,提供了一个用于编辑布尔值的UI。有一个相关的操作和一个reducer来更新状态。我知道如何使其适用于该州的特定属性。但是,我如何创建组件(和相关的缩减程序)来使用存储中的任何布尔值,而不是为每个组件创建一个特殊的缩减程序呢?

假设状态是这样的:

代码语言:javascript
运行
复制
{
  items: {
    house: { isBig:true, location: ... },
    car: { isMine:true, isBroken:false, ... }
  },
  books: [
    { id:1, available:true, title:... },
    { id:2, available:false, title:... }, ...
  ]
}

要创建各种MySwitch实例来查看和编辑任何给定值-如items.house.isBigitems.car.isMinebooks[1].available -并使用相同的reducer更新它们,正确的机制是什么?

我可以使用connect将属性注入到组件中,如下所示:

代码语言:javascript
运行
复制
ASwitch = connect(state => ({
  valueToEdit: state.items.car.isMine
})(MySwitch)

但我不知道如何将它传递给reducer,以及如何让它更新状态的相应部分。我想我可以提供操作的路径(即"items.car.isMine"):

代码语言:javascript
运行
复制
export const editBoolean = ( path, value ) => {
  return {
    type: 'BOOL_EDIT',
    payload: { path, value }
  }
}

然后在reducer中使用类似这样的东西:

代码语言:javascript
运行
复制
case 'BOOL_EDIT': {
  const { path, value } = action.payload;
  return {
    ...state,
    [path]: value
  }
}

但它不起作用,似乎ES6不支持变量计算属性,而是创建了一个像state["items.car.isMine"]这样的属性。

我不知道该怎么继续下去。谢谢你的帮助。

EN

Stack Overflow用户

发布于 2018-09-21 12:43:27

我认为你的想法是正确的,但你的问题并不是针对redux的,你只需要克隆你的状态和你希望通过你的路径指向的更新后的节点。

你可以使用类似这样的东西

代码语言:javascript
运行
复制
const singlePathReducer = (state, { payload: { path, value } }) => path.reduce(({ nextState, branch = nextState }), node) => {
  if (node !== path[path.length - 1]) {
    // this was the part you were missing; you need to walk down your state tree
    // by passing a reference of the current branch to the next reduce callback
    return { nextState, branch: nextState[node] };
  }

  // mutate your nextState, this is ok
  branch[node] = value;
  return nextState;

  // don't mutate state, create a copy
}, { nextState: { ...state } });

如果我没有弄错在js中通过引用传递的工作原理,这应该是有效的。完整的实现如下所示(保持您的singlePathReducer fn独立可以更容易地进行单元测试):

代码语言:javascript
运行
复制
const rootReducer = (state, action) => {
  switch action.type {
    case 'BOOL_EDIT':
      return singlePathReducer(state, action);
    default:
      return state;
  }
};
票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52436020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档