在React中使用setState修改数组的值时,为什么不能使用数组的可变方法(push、unshift等)? 但在vue中可以
一、为什么React中修改数组时不能使用数组的可变方法
在React中使用setState
修改数组的值时,不推荐使用数组的可变方法(如push、unshift等)。这是因为React会对比新旧状态,在发现状态变化后,更新组件的渲染。但当你调用可变方法修改数组时,虽然数组已经被改变,但数组的地址并没有发生变化,React并不会察觉到这个变化,也就不会更新组件。
相反,应该遵循以下原则来正确地进行数组操作:
创建一个新数组,将新值推入其中
将新数组传递给setState
来更新组件
以下代码演示了如何在React中创建新数组并更新状态:
this.setState(prevState => ({
myArray: [...prevState.myArray, newValue]
}));
以上代码中,我们使用扩展运算符...
来创建一个新数组,并将原有数组中所有元素放入其中(即展开),再将新的值推入新数组中。最后,我们将新数组作为参数传递给setState
函数。由于我们返回的是一个新对象,而不是直接引用旧对象,所以React能够正确地检测到状态变化并更新组件。
同样的,如果要从数组中删除元素,也应该创建一个新数组并将元素排除在外,如下所示:
this.setState(prevState => ({
myArray: prevState.myArray.filter(element => element !== valueToRemove)
}));
在上面的代码片段中,我们使用Array.filter()
方法从原数组中过滤掉要移除的元素,并返回一个新数组。最后,我们将这个新数组传递给setState
,以更新组件状态。
二、Vue中为什么可以直接用数组可变方法来修改数组
相反的,在vue中直接使用数组可变方法(push, unshift等)改变data中的数组,是因为vue使用了响应式系统来实现数据的双向绑定。
当一个组件中的数据对象被包装成响应式对象后,vue会追踪这个对象,并自动在其属性被访问和修改时发出通知。这就使得 vue 能够在组件更新之后,检测到需要重新渲染的地方,从而做到数据与视图的联动。
对于数组,vue同样对它进行了包装,即定义了一系列能够触发视图更新的 array mutation method(变异方法),如push, pop, shift, unshift等。这些变异方法是通过重写数组原型上的方法来实现的,当触发这些方法时,同时也会触发vue的通知机制,从而更新视图。
因此,在vue中我们可以放心地直接使用push、unshift等可变方法来改变数组而不必担心视图不会更新。