React Context 组件不会在状态改变时更新

React Context components wont update when state changed

我正在尝试在功能组件中创建一个 React 上下文提供程序。我正在使用 useState 挂钩为其他组件提供一个数组,并有一个将新值推送到数组的添加函数。数组和添加函数都是通过上下文提供程序提供的。

好像是通过做

使用带有state hooks的push
var newArray = array
newArray.push("text")
setArray(newArray)

不会导致使用状态的组件重新呈现,但在使用

setArray(array=> [...array, "text"])

使用通过上下文提供程序提供的数组的组件进行更新。

谁能解释这是为什么?

当您使用扩展运算符 ... 设置状态时,您正在创建新对象。如果您不使用它,并且您正在使用旧对象 React 设置状态,则不会更新您的组件,因为状态 属性 没有改变(对对象的引用没有改变)。正如我在开头所说,使用 [... array] 实际上是在创建新对象(新引用),因此 React 会更新状态。

了解状态变化。

在 React 中,您不得为了重新渲染而改变状态。如果您将对象推送到数组中,那就是突变,它不会为该状态变量创建新的引用,并且 React 无法确定它是否已更新。 React 使用浅层比较,所以即使数组的内容不同,引用也是相同的。您需要更新引用才能触发渲染。

数组在 javascript 中是可变的,因此当您创建一个变量并将其指向一个数组时(如您的示例)

var newArray = array

newArray 实际上并不复制它的实例,而只是存储对它的引用。您可以在下面看到的浏览器控制台中完成的一个非常简单的示例中看到这一点

当你通过推入一个新变量来改变你的例子中的数组时,它只会将它添加到初始数组中,改变状态而不导致重新渲染。当您调用 setArray 到新数组后 React 协调时,它发现数组(引用)是相同的并且不会导致重新渲染。

当您使用扩展符号示例时,您正在使用 [] 创建一个新数组,只是 new Array 的语法糖并将旧数组中的项目清空到新数组中。当它比较旧状态、新状态及其新项目时,React 发现了差异并重新呈现您的组件。

但是,如果您希望按照最初设定的方式进行操作,您可以使用 .slice() 数组函数,以便使用被调用数组中存在的数据创建一个新数组它将是 var newArray = array.slice()。如果您将一个项目添加到新数组并设置状态,它将重新呈现。