React Context 组件在状态更改时不会更新
Posted
技术标签:
【中文标题】React Context 组件在状态更改时不会更新【英文标题】:React Context components wont update when state changed 【发布时间】:2020-07-18 14:43:33 【问题描述】:我正在尝试在功能组件中创建反应上下文提供程序。我正在使用 useState 挂钩为其他组件提供一个数组,并具有一个将新值推送到数组的添加函数。数组和添加函数都是通过上下文提供者提供的。
似乎是通过这样做来使用带有状态钩子的推送
var newArray = array
newArray.push("text")
setArray(newArray)
不会导致使用状态的组件而是在使用时重新渲染
setArray(array=> [...array, "text"])
使用通过上下文提供程序提供的数组的组件会更新。
谁能解释这是为什么?
【问题讨论】:
【参考方案1】:数组在 javascript 中是可变的,所以当你创建一个变量并将它指向一个数组时(就像你的例子一样)
var newArray = array
newArray 实际上并不复制它的实例,而只是存储对它的引用。您可以在下面的浏览器控制台中的一个非常简单的示例中看到这一点
当您通过推入一个新变量来改变示例中的数组时,它只会将其添加到初始数组中,从而改变状态并且不会导致重新渲染。当 React 在你调用 setArray 到新数组后进行协调时,它会看到数组(引用)是相同的并且不会导致重新渲染。
当您使用扩展符号示例时,您正在使用[]
创建一个新数组,只是new Array
的语法糖并将旧数组中的项目清空到新数组中。当它将旧状态与新状态及其新项目进行比较时,React 会发现差异并重新渲染您的组件。
但是,如果您希望按照最初设定的方式执行此操作,则可以使用 .slice() 数组函数,以便使用正在调用的数组中存在的数据创建一个新数组,这样它就会是var newArray = array.slice()
。如果您将一个项目添加到新数组并设置状态,它将重新呈现。
【讨论】:
【参考方案2】:当您使用扩展运算符...
设置状态时,您正在创建新对象。如果您不使用它,并且您正在使用旧对象设置状态 React
将不会更新您的组件,因为 state 属性没有改变(对对象的引用没有改变)。正如我在开头所说,使用[... array]
实际上是在创建新对象(新引用),因此 React 会更新状态。
【讨论】:
【参考方案3】:阅读状态突变。
在 react 中,您不能为了重新渲染而改变状态。如果您将对象推送到数组中,那就是突变,它不会为该状态变量创建新的引用,并且反应无法确定它是否已更新。 React 使用浅比较,因此即使数组的内容不同,引用也是相同的。您需要更新引用才能触发渲染。
【讨论】:
以上是关于React Context 组件在状态更改时不会更新的主要内容,如果未能解决你的问题,请参考以下文章
React Native 更改 let 值不会在子组件中更改为道具