深入研究多嵌套数组语法糖

时间:2017-06-01 14:30:59

标签: javascript ecmascript-6 redux syntactic-sugar ecmascript-7

当我需要深入研究数据结构时,我经常发现自己遵循这种模式,特别是在我的Redux reducer中:

state.items = state.items.map((item) => {
  item.subItems = item.subItems.map((subItem) => {
    subItem.bottomItems = subItem.bottomItems.map((bottomItem) => {
      // do something with bottomItem...
      bottomItem.foo = 'bar';
      return bottomItem;
    });
    return subItem;
  });
  return item;
});

这似乎是很多样板,可以达到bottomItems级别。

ES6或ES7是否提供了一些语法糖来缓解这种模式?

2 个答案:

答案 0 :(得分:2)

我应该首先提到的是,你所拥有的代码会修改原始状态。要维护redux的state immutability principle,您只想返回新对象而不是修改现有对象。

就简单的语法而言,如果使用arrow functionsobject spread,这种模式并不是那么糟糕:

return {
  items: state.items.map(item => ({
    ...item,
    subItems: item.subItems.map(subItem => ({
      ...subItem,
      bottomItems: subItem.bottomItems.map(bottomItem => ({
        ...bottomItem,
        foo: 'bar' // update foo to 'bar' for every bottomItem in every subItem in every item
      })
    })
  })
}

请注意,对象传播还不是该语言的一部分,它目前是第3阶段提案,可能会成为下一个ECMAScript版本的一部分。因此,您必须使用像Babel这样的东西来在当今的浏览器中工作。

如果您不希望这样做,并且想要今天可以使用的功能,则可以使用Object.assign代替:

return {
  items: state.items.map(item => Object.assign({}, item, {
    subItems: item.subItems.map(subItem => Object.assign({}, subItem, {
      bottomItems: subItem.bottomItems.map(bottomItem => Object.assign({}, bottomItem, {
        foo: 'bar' // update foo to 'bar' for every bottomItem in every subItem in every item
      })
    })
  })
}

由于您似乎想要更清晰,更易读的语法,我建议选项1:)

答案 1 :(得分:1)

是的,嵌套的不可变更新可能很麻烦(正如我在Redux文档的Structuring Reducers - Immutable Update Patterns部分中提到的那样)。

您可能希望使用其中一个不可变更新实用程序库。这些库提供了各种语法和抽象,用于执行更简单的嵌套不可变更新。一些使用字符串键路径,另一些使用嵌套对象定义。典型示例可能是someLib.set(["items", "subItems", "bottomItems", 0, "someField"], someValue)

请参阅Immutable Data#Immutable Update UtilitiesRedux addons catalog部分,了解可用的库列表。