我将React与功能组件和钩子一起使用-我试图添加一个滚动侦听器,该滚动侦听器根据状态的当前值修改状态。
我当前的代码如下:
const [isAboveTheFoldVisible, setAboveTheFoldVisible] = useState(true);
const scrollHandler = useCallback(
() => {
if (window.pageYOffset >= window.innerHeight) {
if (isAboveTheFoldVisible) {
setAboveTheFoldVisible(false);
}
} else if (!isAboveTheFoldVisible) {
setAboveTheFoldVisible(true);
}
},
[isAboveTheFoldVisible]
);
useEffect(() => {
window.addEventListener('scroll', scrollHandler);
return () => {
window.removeEventListener('scroll', scrollHandler);
};
}, [scrollHandler]);
但是,由于useEffect中使用了[scrollHandler],因此在设置isAboveTheFoldVisible时会删除并重新添加侦听器……这是不必要的。
我看到的可能解决方案:
有两个useEffect
,一个添加滚动侦听器,并设置类似滚动位置的状态,而不读取任何内容
const [scrollPosition, setScrollPosition] = useState(0)
然后第二次将scrollPosition
作为[scrollPosition]
。
我不太喜欢这种解决方案,因为并不清楚为什么当您看到监听器时我们要设置scrollPosition
。
使用自定义钩子,如useEventListener https://usehooks.com/useEventListener/
使用ref引用处理程序。
无论如何都不要读取isAboveTheFoldVisible
的值并设置新状态。 React将旧状态与新状态进行比较,如果相同,则不会重新渲染。