javascript-更新redux中的嵌套数据

使用Redux更新商店中嵌套数据数组的最佳/正确方法是什么?

我的商店看起来像这样:

{
    items:{
        1: {
            id: 1,
            key: "value",
            links: [
                {
                    id: 10001
                    data: "some more stuff"
                },
                ...
            ]
        },
        ...
    }
}

我有一对异步操作来更新完整的items对象,但是我还有另一对操作要更新特定的links数组。

我的减速器当前看起来像这样,但是我不确定这是否是正确的方法:

  switch (action.type) {
    case RESOURCE_TYPE_LINK_ADD_SUCCESS:
      // TODO: check whether the following is acceptable or should we create a new one?
      state.items[action.resourceTypeId].isSourceOf.push(action.resourceTypeLink);
      return Object.assign({}, state, {
        items: state.items,
      });
  }
Clarkie asked 2020-02-29T15:12:13Z
2个解决方案
58 votes

乔尼的答案是正确的(永远都不会改变赋予您的状态!),但我想再加一点。 如果所有对象都具有ID,则保持状态形状嵌套通常不是一个好主意。

这个:

{
  items: {
    1: {
      id: 1,
      links: [{
        id: 10001
      }]
    }
  }
}

是很难更新的形状。

不必是这种方式! 您可以这样存储它:

{
  items: {
    1: {
      id: 1,
      links: [10001]
    }
  },
  links: {
    10001: {
      id: 10001
    }
  }
}

因为任何实体只有一个规范副本,所以更新起来容易得多。 如果需要让用户“编辑链接”,则只需在一个地方进行更新即可,它完全独立于items或任何其他有关links的内容。

为了使您的API响应达到这种形状,您可以使用normalizr。 将服务器操作中的实体标准化后,您可以编写一个简单的化简器,将其合并为当前状态:

import merge from 'lodash/object/merge';

function entities(state = { items: {}, links: {} }, action) {
  if (action.response && action.response.entities) {
    return merge({}, state, action.response.entities);
  }

  return state;
}

请参阅Redux real-world示例,以获取这种方法的演示。

Dan Abramov answered 2020-02-29T15:13:28Z
50 votes

React的update()不变性助手是一种无需更改即可创建普通旧JavaScript对象更新版本的便捷方法。

您给它提供了要更新的源对象和一个对象,该对象描述了需要更新的片段的路径以及需要进行的更改。

例如,如果某个操作具有action.idlink属性,而您想将link推到以id为键的项中的链接数组:

var update = require('react/lib/update')

// ...

return update(state, {
  items: {
    [action.id]: {
      links: {$push: action.link}
    }
  }
})

(示例对action.id使用ES6计算的属性名称)

Jonny Buchanan answered 2020-02-29T15:12:41Z
translate from https://stackoverflow.com:/questions/32135779/updating-nested-data-in-redux-store