我有一个应为我的标头的react函数。到达滚动按钮后,此标题将更改其背景颜色。
为此,我使用滚动事件侦听器并跟踪其相对于按钮的位置。这对于setTransparent(false)
来说是很好的方法,但对setTransparent(true)
来说则不是:
在监听器中记录transparent
会返回true
,即使将其设置为{{1 }}内的第一个if语句中。
如何?这里的最佳做法是什么?
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);
}
});
}, [])
将使其起作用,但这将在每次更新时甚至添加侦听器。
答案 0 :(得分:2)
效果回调中的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
之外的符号)。