gpt4 book ai didi

javascript - React useState 不会在窗口事件中更新

转载 作者:行者123 更新时间:2023-12-03 20:21:14 28 4
gpt4 key购买 nike

状态确实在滚动上设置,但从事件监听器记录,它似乎停留在初始值。

我想这与 scrolling 有关在定义副作用时设置,但我怎么能从滚动触发状态更改?我认为的任何窗口事件也是如此。

这是一个代码框示例:https://codesandbox.io/s/react-test-zft3e

  const [scrolling, setScrolling] = useState(false);

useEffect(() => {
window.addEventListener("scroll", () => {
console.log(scrolling);
if (scrolling === false) setScrolling(true);
});
}, []);

return (
<>
scrolling: {scrolling}
</>
);

最佳答案

所以你的匿名函数被锁定在 scrolling 的初始值上。 .这就是闭包在 JS 中的工作方式,你最好找到一些关于它的漂亮文章,这可能会有些棘手,并且钩子(Hook)严重依赖闭包。
到目前为止,这里有 3 种不同的解决方案:
1. 在每次更改时重新创建和重新注册处理程序

useEffect(() => {
const scrollHandler = () => {
if (scrolling === false) setScrolling(true);
};
window.addEventListener("scroll", scrollHandler);
return () => window.removeEventListener("scroll", scrollHandler);
}, [scrolling]);
在遵循此路径时,请确保您是 returning cleanup函数来自 useEffect .这是很好的默认方法,但对于滚动它可能会影响性能,因为滚动事件触发太频繁。
2.通过引用访问数据
const scrolling = useRef(false);

useEffect(() => {
const handler = () => {
if (scrolling.current === false) scrolling.current = true;
};
window.addEventListener("scroll", handler);
return () => window.removeEventListener("scroll", handler);
}, []);

return (
<>
scrolling: {scrolling}
</>
);
缺点:更改 ref 不会触发重新渲染。所以你需要有一些其他的变量来改变它来触发重新渲染。
3.使用setter的功能版本来访问最新的值
(我认为这是首选方式):
useEffect(() => {
const scrollHandler = () => {
setScrolling((currentScrolling) => {
if (!currentScrolling) return true;
return false;
});
};
window.addEventListener("scroll", scrollHandler);
return () => window.removeEventListener("scroll", scrollHandler);
}, []);
注意顺便说一句,即使是一次性使用效果,您最好还是返回清理功能。
PS 另外现在你没有设置 scrollingfalse , 所以你可以摆脱条件 if(scrolling === false) ,但可以肯定的是,在现实世界的场景中,您也可能会遇到类似的情况。

关于javascript - React useState 不会在窗口事件中更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60540985/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com