javascript - 状态更改后未触发 useEffect Hook
问题描述
我有两个兄弟组件通过上下文在反应中共享状态。组件之间的共享状态是一个数组。
如果我arr
在一个组件中更新状态,我希望另一个组件监听该更新并做相应的事情。当我useEffect
在第二个组件中使用时,我会监听arr
状态变量的变化。
例如:
// App Component -------
const App = props => {
const { arr, setArr } = useContext(GlobalContext)
const handleChange = () => {
const newArr = arr
[10, 20, 30, 40].map(v => {
newArr.push(v)
setArr(newArr)
})
return (...)
}
// App2 (Sibling) Component
const App2 = props => {
const { arr, setArr } = useContext(GlobalContext)
const [localArr, setLocalArr] = useState(0)
useEffect(
() => {
updateLocalState()
},
// fire if "arr" gets updated
[arr]
)
const updateLocalState = () => {
setLocalArr(localArr + 1)
}
return (...)
}
该useEffect
钩子仅在初始渲染时触发,尽管处于arr
更新状态。
我知道const newArr = arr
向我的状态变量声明一个新变量是一个引用,因此newArr.push(v)
在技术上是一个状态突变。但是,状态仍然会更新,不会引发任何警告,并且useEffect
什么也不做。
为什么useEffect
虽然状态更新了却没有被调用?是因为状态突变吗?
第二个问题:为什么没有关于状态突变的警告或错误?状态突变是危险的——如果发生这种情况,我希望得到某种警告。
现场演示:
解决方案
您作为第二个参数传递的数组useEffect
仅检查数组中===
的元素是否与前一次渲染中的元素相同。const newArr = arr;
将导致,newArr === arr
因为它不会创建一个新数组,这不是你想要的。
创建一个包含所有元素的新数组,arr
它将按预期工作。
const App = props => {
const { arr, setArr } = useContext(GlobalContext)
const handleChange = () => {
const newArr = [...arr]
[10, 20, 30, 40].forEach(v => {
newArr.push(v)
})
setArr(newArr)
}
return <>{/* ... */}</>
}
推荐阅读
- database - 如何将 MS Access 数据库 (.mdb) 文件转换为 Sqlite?
- javascript - asp.net 返回部分视图的内容
- java - 多个矩形的 Java 2D Platformer 碰撞检测
- c++ - 更简单的 c++ 模板编译错误输出
- azure-service-fabric - ServiceFabric / IFabricSecretStoreClient / COM 异常
- python - 100% Accuracy 使用 SVC 分类,一定有问题吗?
- java - 如何使整数输入出现在提示用户输入的消息之后而不是之前?
- linux - Buildroot Linux 的内核恐慌
- mysql - 了解 Handlebars、Express 和 Node.js 背后的基础知识
- jython-2.7 - 在今天以外的日子打开旅行计划脚本较慢