React-更新状态(对象数组)。我需要深度复制阵列吗?

时间:2019-05-24 15:59:36

标签: javascript reactjs react-hooks

我有以下state

const[images,setImages] = useState([
  {src: 'stringSRC1', selected: false},
  {src: 'stringSRC2', selected: false},
  {src: 'stringSRC3', selected: false}
]);

我正在使用以下代码对其进行更新(切换所选状态):

function handleImageClick(index) {
  props.setImages((prevState)=>{
    const aux = Array.from(prevState);
    aux[index].selected = !aux[index].selected;
    return aux;
  });
}

它按预期工作。但是我想到了一件事。

当我从prevState复制数组时,我正在创建一个新数组,但是对象(存储为引用)将保持不变。当您像这样复制数组时,它们不会改变。

问题

这是不好的做法吗?我是否应该像在创建新数组和创建全新对象中那样费心去深度复制数组?或者这还好吗?

2 个答案:

答案 0 :(得分:0)

不,这是应该的工作方式。是的,对象没有改变,但是这里重要的是数组改变了。当事情发生变化时,React会在DOM和虚拟DOM之间进行比较。一旦将新阵列与旧阵列进行比较,就可以检测到更改,阵列本身的内容并不重要。

答案 1 :(得分:0)

是的,如果要避免副作用,必须深度克隆。

在您的职能中:

function handleImageClick(index) {
  props.setImages((prevState)=>{
    const aux = Array.from(prevState);
    aux[index].selected = !aux[index].selected;
    return aux;
  });
}

在使用Array.from时,您将获得对存储对象的引用,因此prevState会被修改。

看到这个:

setTest(prevState => {
      console.log("PrevState", prevState);
      const b = Array.from(prevState);
      b[0].a = b[0].a + 1;
      return b;
    });

您可以在这里进行测试:

https://codesandbox.io/embed/exciting-mcnulty-6spdh?fontsize=14

您将看到prevState具有下一个值,因此您丢失了prevState值。

想象一下您想在代码中执行此操作:

function handleImageClick(index) {
      props.setImages((prevState)=>{
        const aux = Array.from(prevState);
        aux[index].selected = !aux[index].selected;
        aux[index + 1].selected = prevState[index].selected;
        return aux;
      });
    }

aux[index + 1].selected = prevState[index].selected;坏了!

因此,您需要深度复制数组以避免这种情况。

您可以这样做:const aux = JSON.parse(JSON.stringify(prevState));