有人能向我解释一下,为什么在useState中将值(通过单击按钮(从"init"更改为"new state"后,addEventListener的回调显示值"init",而按钮中的文本为"new state">
function Test() {
const [test, setTest] = useState("init")
useEffect(() => {
window.addEventListener("resize", () => console.log(test))
}, [])
return (
<button style={{ marginTop: "100px" }} onClick={() => setTest("new state")}>
{test}
</button>
)
}
将test
添加到useEffect
:中的依赖数组
useEffect(() => {
const func = () => console.log(test);
window.addEventListener("resize", func)
return () => {
window.removeEventListener("resize", func)
}
}, [test])
Hooks常见问题解答中介绍了为什么需要这样做的解释:为什么我在函数中看到过时的道具或状态?:
您看到过时道具或状态的另一个可能原因是使用"依赖数组"优化,但未正确指定所有依赖项。例如,如果效果将
[]
指定为第二个参数,但读取内部的someProp
,它将继续"看到"CCD_ 5的初始值。解决方案是移除依赖数组,或修复它。
空依赖数组充当componentDidMount。您应该将测试添加为依赖项之一,以便它再次启动
function Test() {
const [test, setTest] = useState("init")
useEffect(() => {
window.addEventListener("resize", fun)
return () => {
window.removeEventListener("resize", fun)
}
}, [test])
return (
<button style={{ marginTop: "100px" }} onClick={() => setTest("new state")}>
{test}
</button>
)
}
发生这种情况的另一个原因是功能组件正在使用过时的状态值。
使用useEffect在组件装载上注册一次事件。在整个组件寿命期间,它是相同的函数,并且引用在第一次定义此eventListener时新鲜的过时状态。
解决方案是使用refs
结账https://codesandbox.io/s/serverless-thunder-5vqh9更好地理解的解决方案
一次激发的效果内的状态永远不会更新(如果使用[](
useEffect范围内的"test"值从未更新,因为该效果在挂载时只激发过一次。之后所做的State更改永远不会更改此值,除非您再次激发Effect,但将参数传递到方括号中。