reactjs - 如何在不明确提供大量操作上下文的情况下更改深层嵌套状态?

标签 reactjs redux

我有嵌套了几层深度的项目:

const initialState = {
  sections: [
    {
      name: 'Section 1',
      categories: [
        {
          name: 'Category 1',
          checklist: [
            { name: 'Item 1', checked: false },
            { name: 'Item 2', checked: true },
            { name: 'Item 3', checked: false },
          ]
        },
        // more categories
      ],
    },
    // more sections
  ],
};

我想知道是否有一种方法可以在不显式传递大量上下文的情况下更改其状态(例如,切换 checked 属性):

function toggleCheckbox(sectionId, categoryId, itemId) {
  return {
    type: 'TOGGLE_CHECKBOX',
    sectionId: sectionId,
    categoryId: categoryId,
    itemId: itemId,
  };
}

function reducer(state = initialState, action) {    
  switch (action.type) {
    case 'TOGGLE_CHECKBOX':
      return Object.assign({}, state, {
        sections: state.sections.map(function (section, i) {
          return i === action.sectionId ? Object.assign({}, section, {
            categories: section.categories.map(function (category, j) {
              return j === action.categoryId ? Object.assign({}, category, {
                checklist: category.checklist.map(function (item, k) {
                  return k === action.itemId ? Object.assign({}, item, {
                    checked: !item.checked,
                  }) : item;
                }),
              }) : category;
            }),
          }) : section;
        }),
      });
    default:
      return state;
  }
}

随着部分、类别和 list 的逻辑增长,我可能希望将它们提取为单独的 reducer ,但因为它们是嵌套的,所以我看不出有什么方法可以做到这一点。

这是一个bin这个商店用 React 可视化。

我想我的问题有两个部分:

  1. 如何将它们提取为单独的 reducer ?
  2. 如何避免显式提供如此多的上下文并避免所有实际上仅更改嵌套项状态的映射?

最佳答案

嵌套对象肯定会很痛苦。 Dan 在 Redux docs 中有一些关于嵌套实体的简介。 。

If you have nested entities, or if you let users edit received entities, you should keep them separately in the state as if it was a database. In pagination information, you would only refer to them by their IDs. This lets you always keep them up to date.

我做了一个 jsbin修改您的示例以进行演示,但其要点包括稍微展平您的状态树。

const initialState = {
  sections: [
    {
      name: 'Section 1',
      categories: [ 'Category 1'],
    },
    // more sections
  ],
  categories: [
    {
      name: 'Category 1',
      checklist: ['Item 1', 'Item 2', 'Item 3']
    },
  ],
  items: [
    {
      name: 'Item 1',
      checked: false
    },
    {
      name: 'Item 2',
      checked: true
    },
    {
      name: 'Item 3',
      checked: false
    },
  ]

};

项目缩减器现在只需要一个名称即可知道要更新哪个项目,并且部分/类别会跟踪它们拥有哪些项目。现在,您可以拆分专用的类别、部分和项目缩减器,每个缩减器都可以处理自己关注的领域!

如果您想要不同类别中具有相同名称的项目,则必须引入一个新 ID 以使它们彼此分开...但目前使用名称是最简单的

关于reactjs - 如何在不明确提供大量操作上下文的情况下更改深层嵌套状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35241718/

相关文章:

javascript - 未捕获的 DOMException : Failed to execute 'querySelector' on 'Document' : '' is not a valid selector

reactjs - 路由更改时状态不会重置 - React-redux-router

javascript - 我的初始页面加载布局阶段花费了超过 2 秒

javascript - 了解 UI 何时在 React/Redux 中准备就绪

javascript - redux-thunk 调度事件

javascript - ngrx效果中api调用后获取数据

javascript - 写 Action 和 reducer 高效且干净(react redux)

reactjs - 如何在 Material-UI 调色板的主要、浅色和深色差异之间切换

javascript - Redux - 取消订阅监听器如何工作?

javascript - 设置 `value` 时出现错误 Dropdown `multiple` 必须是一个数组。收到类型: `[object String]`