使用 Object.assign 更新嵌套对象

Posted

技术标签:

【中文标题】使用 Object.assign 更新嵌套对象【英文标题】:Update nested object using Object.assign 【发布时间】:2018-03-27 11:12:50 【问题描述】:

我有以下对象。当用户单击按钮时,此对象会被分配一个新值。

state = 
  title: '',
  id: '',
  imageId: '',
  boarding: 
    id: '',
    test: '',
    work: 
      title: '',
      id: ''
    
  

我更新的对象如下所示:

state = 
  title: 'My img',
  id: '1234',
  imageId: '5678-232e',
  boarding: 
    id: '0980-erf2',
    title: 'hey there',
    work: 
      title: 'my work title',
      id: '456-rt3'
    
  

现在我想更新状态内的工作对象并保持一切不变。当对象没有嵌套但混淆嵌套时,我使用了Object.assign()

Object.assign(, state,  work: action.work );

我的 action.work 拥有整个工作对象,但现在我想将其设置为登机,但这会替换登机中的所有内容,这不是我想要的。

【问题讨论】:

【参考方案1】:

您应该手动合并深层对象属性,尝试以下操作:

Object.assign(, state,  
  boarding: Object.assign(, state.boarding, 
    work: action.work
  
);

或使用扩展运算符


  ...state,
  boarding: 
    ...state.boarding,
    work: action.work
  

【讨论】:

您能否解释一下传播运算符在您的示例中的作用以及它与您的第一个合并深度道具有何不同? @fscore 我刚刚在这个话题上找到了很好的link,相信你会喜欢的! @dhilt:带有扩展运算符的示例是一个很好的例子,但它应该分配给state 或一个常量或变量。它的发布方式会导致错误和混淆用户会使用它,就像我会举的例子一样:state = ...state, boarding: ...state.boarding, work: action.work 【参考方案2】:

如果无法按照@dhilt 的建议手动合并它们,请查看lodash's merge

如果您想自定义合并行为,可以使用mergeWith,例如合并数组而不是覆盖。

【讨论】:

【参考方案3】:

您可以使用 Object.assign 来更新嵌套对象,例如:

Object.assign(state.boarding,  work: action.work )

这将使用新的工作属性更新现有状态。

【讨论】:

这不会返回state,而是state.boarding 我没有说它会返回它,我说它会更新状态。 其实我错了。在大多数情况下,这甚至无法编译。即使这样做,它的影响也为零。请阅读文档:developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 很抱歉,您应该删除此答案,因为它完全错误。否则我会投反对票。【参考方案4】:

如果您只想更新work,则不需要任何形式的合并。做吧

state.boarding.work = action.work;


您是否担心不可变性,您可以复制state,然后更新work

【讨论】:

【参考方案5】:

我可以看到您正在使用 Redux。文档中有一篇很棒的文章关于以不可变的方式更新对象。我建议你阅读它:http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html

此外,人们通常为此使用库,例如​​ Immutable.js 或 seamless-immutable,它们不会让您的代码看起来令人恶心:)

【讨论】:

以上是关于使用 Object.assign 更新嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章

浅谈ES6的Object.assign()浅拷贝

在反应中更新嵌套状态

vue中data值改变但页面视图不刷新问题

为啥要使用 Object.assign() 来更新功能组件 props 的变化?

Object.assign()的使用

JS中实现深度拷贝,复制一个对象