Redux:为什么做一层状态的浅拷贝是错误的? [英] Redux: Why making a shallow copy of one level of the state is a mistake?

查看:31
本文介绍了Redux:为什么做一层状态的浅拷贝是错误的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读有关在 Redux 中更新嵌套状态对象的文档时,我偶然发现了这个 常见错误,其中指出仅对顶层对象进行浅拷贝是不够的:

While reading the documentation about updating nested state object in Redux, I stumbled upon this common mistake, which states that doing a shallow copy of the top level object is not sufficient:

function updateNestedState(state, action) {
    // Problem: this only does a shallow copy!
    let newState = {...state};

    // ERROR: nestedState is still the same object!
    newState.nestedState.nestedField = action.data;

    return newState;
}

但我不知道为什么它不够用,因为从技术上讲它是有效的,正如你在这个小提琴中看到的:https://codesandbox.io/s/D9l93OpDB

but I couldn't find out why it isn't sufficient, because technically it's working, As you can see in this fiddle: https://codesandbox.io/s/D9l93OpDB

我很乐意对此声明进行进一步的澄清/解释,也很乐意举例说明更新此类状态对象的最佳做法是什么.

I'll be happy for further clarification/explanation regarding this statement, and also will be happy for an example of what is the best practice of updating such state objects.

谢谢!

推荐答案

假设你有一个这样的状态对象:

Assume you have a state object like that:

let state = { a: { b: 1 } };

let cp = { ...state }

cp.a === state.a //true, that means that those are the exact same objects.

那是因为 »inner« 对象 (state.a) 是通过引用添加到 cp 的.如果你现在这样做:

that is because the »inner« Object (state.a) is added to cp by reference. If you now do:

cp.a.b = 10;

您也在 state.a.b 中更改值.所以这里的错误是:如果你想修改 state.a.b,那么你必须用一个新的对象替换它,有一个像这样的新值:

You change the value also in state.a.b. So the mistake here is: if you want to modify state.a.b, than you have to replace that with a new Object, having a new value like so:

let cp = {
  ...state,
  a: {
     ...state.a.b
     b: 2
  }
}

这样做的原因是要求您编写»纯«函数,解释一下:

The reason for this is that you are asked to write »pure« functions, to explain consider this:

var a = { b: 1 };

//not a pure function
function foo (obj) {
  obj.b++;
  return obj;
}

for (var i = 0; i < 10; i++) foo(a);
//a.b = 11;

所以每次调用foo(a)都会修改对象,会产生不同的输出并修改一个全局变量.

So the object is modified each call of foo(a) will produce different output and modify a global variable.

以上内容可能会导致您遇到非常讨厌的错误,这些错误很难找到并防止您遇到这种情况,请选择以下内容.

The above can lead you to really nasty bugs, which are hard to find and to prevent you from running into this prefer the below.

//a pure function
function bar (obj) {
  return {
    ...obj,
    b + 1
  }
}

for (var i = 0; i < 10; i++) bar(a);
//a.b = 2

在那种情况下 a 没有被修改,所以 bar(a) 的输出将始终产生相同的输出.

In that case a is not modified, so the output of bar(a) will always yield the same output.

这篇关于Redux:为什么做一层状态的浅拷贝是错误的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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