【问题标题】:Using React Hooks To Update w/ Scroll使用 React Hooks 通过滚动更新
【发布时间】:2019-12-18 13:23:47
【问题描述】:

我正在尝试根据个人是否在组件上向下滚动来控制 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">

  ....

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案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.removeEventListener("scroll", onScroll);
      }, [scrollTop]);
    

    【讨论】:

      【解决方案2】:

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

        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 规则中

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

      【讨论】:

      • 你会如何在 Typescript 中输入这个?
      猜你喜欢
      • 1970-01-01
      • 2019-10-18
      • 2020-06-19
      • 2021-03-16
      • 1970-01-01
      • 2019-07-13
      • 2019-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多