【问题标题】:Object.assign - Update Specific PropertyObject.assign - 更新特定属性
【发布时间】:2016-07-06 11:02:43
【问题描述】:

在这里使用 React 和 Redux:

我的State 看起来与此类似:

State : {
   First : {
      prop1 : "a",
      prop2 : "b"
   },
   ...
   Last : {
      prop1 : "c",
      prop2 : "d"
   }
}

我的Reducer 函数如下所示:

const tabsState = ( state = initialTabState, action ) => {
    switch( action.type ) {
    case( ENABLE_TAB ):
        return (
            Object.assign( {}, state, action.payload )
        );
    default:
        return state;
    }
};

对于action.payload,我只想发送包含prop1 新值的数据。我对Object.assign的理解是sources参数只是更新props,不会覆盖state中的对象,对吗?

在上面,我的action.payload是这样的:

   First : {
      prop1 : "z"
   },
   Second : {
      prop2 : "x"
   },
   ...

它似乎覆盖了 State 对象中的 First 和后续对象。也就是说Reducer返回的新State没有每个对象的第二个prop。 prop2s

【问题讨论】:

  • 如果您对深度更新状态有疑问,请考虑将您的数据结构更改为其他内容。例如,请参阅this answer。此外,您可以拆分您的减速器并为FirstSecond 等创建特殊的减速器。

标签: javascript object reactjs redux


【解决方案1】:

我认为您可以使用 Immutable.js。我发现它对于处理 redux 和不改变状态树非常有帮助。对于您的具体情况,您需要 Map.mergeDeep() 的运算符,其中 Map 是您的不可变数据结构。 MergeDeep 的行为就像您在想 Object.assign 一样。 所以对于你的情况

import { fromJS } from 'immutable';
const initialTabState = fromJS({
     {
       First : {
         prop1 : "a",
         prop2 : "b"
       },
     ...
       Last : {
         prop1 : "c",
         prop2 : "d"
       }
     }
})
const tabsState = ( state = initialTabState, action ) => {
    switch( action.type ) {
    case( ENABLE_TAB ):
        return (
            state.mergeDeep(fromJS(action.payload))
        );
    default:
        return state;
    }
};

【讨论】:

  • 谢谢,我现在采用 Immutable。
  • 不错!我真的很喜欢和它一起工作!我觉得这让我很明确。
【解决方案2】:

假设您的状态如下所示:

{
  state: {
    meta: {
      data: {
        foo: 'bar',
      },
    },
  },
}

你希望它看起来像这样:

{
  state: {
    meta: {
      data: {
        foo: 'bar',
        hello: 'world',
      },
    },
  },
}

首先,创建一个函数来更新您想要获取的嵌套属性:

const update = (data, obj) => {
  return Object.assign(
    {},
    data,
    obj,
  )
}

然后,像这样调用 update 函数:

return Object.assign(
  {},
  state,
  {
    meta: {
      data: update(state.meta.data, {hello: 'world'}),
    },
  },
)

【讨论】:

    【解决方案3】:

    您需要像这样使用深度分配来合并对象树。

    https://github.com/sindresorhus/deep-assign

    【讨论】:

    • 感谢大卫告诉我,我的印象是 Object.assign 也可以进行深度合并。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 2018-02-22
    • 2018-01-27
    • 2021-08-14
    • 1970-01-01
    • 2021-10-21
    相关资源
    最近更新 更多