【问题标题】:Update nested object using Object.assign使用 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 拥有整个工作对象,但现在我想将其设置为登机,但这会替换登机中的所有内容,这不是我想要的。

【问题讨论】:

    标签: javascript reactjs ecmascript-6 redux react-redux


    【解决方案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.jsseamless-immutable,它们不会让您的代码看起来令人恶心:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-20
          • 2021-12-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多