javascript - UseEffect 不会使用更新的状态
问题描述
我有一个反应函数,它应该是我的标题。到达滚动按钮后,此标题应更改其背景颜色。
为此,我使用滚动事件侦听器并跟踪其相对于按钮的位置。这适用于setTransparent(false)
,但不适用于setTransparent(true)
:即使将侦听器设置为第一个 if 语句内部,
日志记录也会返回。transparent
true
false
怎么会这样?这里的最佳做法是什么?
const [transparent, setTransparent] = useState(true);
useEffect(() => {
const button = document.querySelector(".hero-button");
window.addEventListener("scroll", () => {
const {bottom} = button.getBoundingClientRect();
if (transparent && bottom <= 0) {
setTransparent(false);
} else if (!transparent && bottom > 0) {
setTransparent(true);
}
});
}, [])
将依赖项设置为transparent
将使其工作,但这将在每次更新时添加甚至监听器。
解决方案
您transparent
在效果回调中的变量仅引用初始渲染上的值,该值始终为true
. 您可以通过在更改时重新添加滚动侦听器来修复它transparent
,并返回一个删除先前处理程序的清理函数:
useEffect(() => {
const button = document.querySelector(".hero-button");
const scrollHandler = () => {
const { bottom } = button.getBoundingClientRect();
if (transparent && bottom <= 0) {
setTransparent(false);
} else if (!transparent && bottom > 0) {
setTransparent(true);
}
};
window.addEventListener("scroll", scrollHandler);
// DON'T FORGET THE NEXT LINE
return () => window.removeEventListener("scroll", scrollHandler);
}, [transparent]);
另一种选择是使用 ref 而不是useState
透明的(或者,useState
如果transparent
更改需要导致重新渲染)。
推荐阅读
- git - 仅在发生更改时使用 husky pre-push 运行测试
- sql - SQL选择HIGHEST时间戳为LOWEST的记录
- c# - 如何在两个场景中使用 Player 游戏对象?
- python - html 条件帮助 - If 语句出现问题
- android - 如何使用 Frida 操作原生 Android 应用程序的静态变量?
- javascript - React onWheel 处理程序无法阻止Default,因为它是一个被动事件监听器
- node.js - 从 s3 损坏的图像
- c# - 失焦时如何接收按键 C# Forms
- javascript - 将“保存图像”javascript 按钮添加到 php 脚本
- bash - 如何使用 bash 将脚本中的一个单词替换为另一个单词?