我试图根据个人是否向下滚动组件来控制React组件的可见性。可见性作为“ in”属性传递到Fade
元素中。
我已经使用UseEffect Hook设置了一个侦听器,该钩子将侦听器添加到onMount。实际的onScroll函数应该先更新scrollTop状态(即到页面顶部的高度的当前值),然后再更新滚动状态(将事件的滚动到页面顶部的状态与先前的状态进行比较,并且如果第一个大于第二个,则返回true)。
但是,由于某种原因,setScrollTop挂钩不起作用,并且滚动状态继续保持为0。
我在做什么错?这是完整的组件:
export const Header = (props) => {
const classes = useStyles();
const [scrolling, setScrolling] = useState(false);
const [scrollTop, setScrollTop] = useState(0);
const onScroll = (e) => {
setScrollTop(e.target.documentElement.scrollTop);
setScrolling(e.target.documentElement.scrollTop > scrollTop);
}
useEffect(() => {
window.addEventListener('scroll', onScroll);
},[]);
useEffect(() => {
console.log(scrollTop);
}, [scrollTop])
return (
<Fade in={!scrolling}>
<AppBar className={classes.header} position="fixed">
....
答案 0 :(得分:4)
您缺少钩子中的依赖项。试试这个:
useEffect(() => {
const onScroll = e => {
setScrollTop(e.target.documentElement.scrollTop);
setScrolling(e.target.documentElement.scrollTop > scrollTop);
};
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, [scrollTop]);
通过在onScroll
内移动useEffect
,您不需要在挂钩的依赖项上进行跟踪,但是由于它使用了组件范围内的scrollTop
,因此您需要添加它。
或者,如果由于某种原因您不想在onScroll
中移动useEffect
定义,则需要将onScroll
包装在useCallback
中并进行跟踪在useEffect
的依赖项数组中。
通常,我建议将react-hooks/exhaustive-deps
添加到您的ESlint规则中
此外,最好在清理功能中删除事件监听器。
答案 1 :(得分:1)
或者您可以使用window.pageYOffset。这样对我来说更容易理解:
const [scrolling, setScrolling] = useState(false);
const [scrollTop, setScrollTop] = useState(0);
useEffect(() => {
function onScroll() {
let currentPosition = window.pageYOffset; // or use document.documentElement.scrollTop;
if (currentPosition > scrollTop) {
// downscroll code
setScrolling(false);
} else {
// upscroll code
setScrolling(true);
}
setScrollTop(currentPosition <= 0 ? 0 : currentPosition);
}
window.addEventListener("scroll", onScroll);
return window.addEventListener("scroll", onScroll);
}, [scrollTop]);