[英]UseEffect won't use updated state
I have a react function which is supposed to be my header.我有一个反应函数,它应该是我的标题。 This header shall change its background color after reaching a button on scroll.
到达滚动按钮后,此标题应更改其背景颜色。
To do so I use a scroll event listener and track its position in relation to the button.为此,我使用滚动事件侦听器并跟踪其相对于按钮的位置。 This works fine for
setTransparent(false)
, but not for setTransparent(true)
:这适用于
setTransparent(false)
,但不适用于setTransparent(true)
:
Logging transparent
inside of the listener returns true
even after setting it to false
inside of the first if-statement.即使在第一个 if 语句中将其设置为
false
后,在侦听器内部记录transparent
也会返回true
。
How so?为何如此? What's the best practice here?
这里的最佳做法是什么?
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);
}
});
}, [])
Setting the dependency to transparent
will make it work, but this will add even listener every time it updates.将依赖项设置为
transparent
将使其工作,但这会在每次更新时添加甚至侦听器。
Your transparent
variable in the effect callback only references the value on the initial render, which is always true
.效果回调中的
transparent
变量仅引用初始渲染上的值,该值始终为true
。 You can fix it by re-adding the scroll listener whenever transparent
changes, and return a cleanup function that removes the prior handler:您可以通过在
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]);
Another option would be to use a ref instead of useState
for transparent (or, in addition to useState
if transparent
changes needs to result in re-rendering).另一种选择是使用 ref 而不是
useState
来实现透明(或者,如果transparent
更改需要导致重新渲染,则除了useState
之外)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.