首页 > 解决方案 > 使用 React Hooks 通过滚动更新

问题描述

我试图根据个人是否向下滚动组件来控制 React 组件的可见性。可见性作为“in”属性传递到Fade元素中。

我已经使用 UseEffect Hook 设置了一个监听器,它在Mount 上添加了监听器。实际的 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">

  ....

标签: javascriptreactjsreact-hooks

解决方案


您缺少挂钩中的依赖项。尝试这个:

  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包装并跟踪它。onScrolluseCallbackuseEffect

一般来说,我建议添加react-hooks/exhaustive-deps到您的 ESlint 规则中

在清理函数中删除事件侦听器也是一个好主意。


推荐阅读