Redux:为什么使用Object.assign如果不执行深度克隆? [英] Redux: why using Object.assign if it is not perform deep clone?

查看:335
本文介绍了Redux:为什么使用Object.assign如果不执行深度克隆?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Redux的一个核心概念是,状态为不可变。但是,我看到很多例子,包括 Redux docs 使用javascript Object.assign 。然后,我在 MDN :

One core concept in Redux is, states are immutable. However, I saw many examples, including in Redux docs using javascript Object.assign. Then, I saw this warning in MDN:


对于深度克隆,我们需要使用其他替代方法,因为
Object.assign()复制属性值。如果源值是对象的
引用,它只复制该引用值。

For deep cloning, we need to use other alternatives because Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.

那么,为什么使用Object 。如果整点是不变的话,请指出?我在这里错过了什么吗?

So, why using Object.assign if the whole point is immutability? Am I missing something here?

推荐答案

让我们来看看你链接的例子:

Let's look at the example you linked:


function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    default:
      return state
  }
}


是的,这是州的浅层副本,创建一个新对象,其中包含旧的,但更新的 visibilityFilter 。但是如果你一致关于不可变地处理对象,那么如果新状态和旧状态共享对其他不可变对象的引用则没有问题。后来,大概是,如果你要改变其他东西,你会遵循相同的模式。在这一点上,我们上面的浅拷贝将继续使用旧的副本,而你的新对象将使用新的。

Yes, that's a shallow copy of state, creating a new object with everything from the old but with an updated visibilityFilter. But if you're consistent about treating objects immutably, then it's fine if the new state and the old state share references to other immutable objects. Later, presumably, if you were to change something else, you'd follow the same pattern. At which point, the shallow copy we made above would continue to use the old one, and your new object would use the new one.

如果你一直应用不变性down,你正在修改的级别上的浅层副本以及它所需的所有父级别。在上面的示例中,修改位于顶层,因此它只是一个副本。

If you apply immutability all the way down, a shallow copy at the level you're modifying and all its parent levels is all you need. In the example above, the modification is at the top level, so it's just the one copy.

但是如果它更深入呢?假设你有这个对象:

But what if it were deeper? Let's say you had this object:

let obj = {
    a: {
        a1: "a1 initial value",
        a2: "a2 initial value"
    },
    b: {
        b1: "b1 initial value",
        b2: "b2 initial value"
    }
};

如果你想更新 a ,那就是就像上面的州例子一样;你只需要一个 obj 的浅层副本就可以了:

If you wanted to update a, that's just like the state example above; you'd do so with just one shallow copy of obj:

obj = Object.assign({}, obj, {a: {a1: "new a1", a2: "new a2"}});

传播属性(目前处于第3阶段,通常在JSX转换器设置中启用,可能会生成ES2018):

or with spread properties (currently at Stage 3, usually enabled in JSX transpiler setups, will probably make ES2018):

obj = {...obj, a: {a1: "new a1", a2: "new a2"}};

但是如果只是想要更新 A1 ?要做到这一点,你需要一份一个 obj (因为如果你不要复制 obj ,你要修改它引用的树,违反委托人):

But what if you just want to update a1? To do that, you need a copy of a and of obj (because if you don't copy obj, you're modifying the tree it refers to, violating the principal):

obj = Object.assign({}, obj, {a: Object.assign({}, obj.a, {a1: "updated a1"})});

或带差价物业:

obj = {...obj, a: {...obj.a, a1: "updated a1"}};

这篇关于Redux:为什么使用Object.assign如果不执行深度克隆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆