React useState,useEffect无法按预期工作

问题描述 投票:0回答:2

我有一个用例,我想用React钩子来解决它,但它没有像我预期的那样工作。

  • 期望:向下滚动时将显示不在顶部,当向后滚动文档顶部时将消失。
  • 当前:向下滚动时不显示顶部,但在文档顶部向后滚动时不会消失。代码沙箱链接:https://codesandbox.io/s/wkroy1r2xl

提前致谢。

reactjs react-hooks
2个回答
3
投票

该组件添加一次事件侦听器:仅在mount上。那时,它添加了handleScroll监听器,该监听器在该特定时间点用特定的isHeaderMoved值“捕获”。每当滚动页面时,将被调用的回调是具有初始isHeaderMoved值的回调。当前的代码基本上一遍又一遍地用handleScroll调用false

简而言之,您需要添加isHeaderMoved作为效果的依赖项。您还应该在效果中移动handleScroll侦听器,因此可以通过hooks eslint插件更正确地跟踪其依赖关系。

  useEffect(
    () => {
      const handleScroll = () => {
        if (window.pageYOffset > 0) {
          if (!isHeaderMoved) {
            setIsHeaderMoved(true)
          }
        } else if (isHeaderMoved) {
          setIsHeaderMoved(false)
        }
      }

      window.addEventListener("scroll", handleScroll)
      return () => {
        window.removeEventListener("scroll", handleScroll)
      }
    },
    [isHeaderMoved],
  )

请参阅Dan Abromov关于该主题的帖子中的这些部分(其中有一些示例可以比我更好地解释它):

如果你有时间的话,值得仔细阅读整个帖子以充分理解事物。


从skyboxer的评论中,我发现这也可行,但我将保留以上所有内容以供参考。

  useEffect(() => {
    const handleScroll = () => {
      setIsHeaderMoved(window.pageYOffset > 0)
    }

    window.addEventListener("scroll", handleScroll)
    return () => {
      window.removeEventListener("scroll", handleScroll)
    }
  }, [])

0
投票

这应该工作,你必须将window.pageYOffsetisHeaderMoved传递给useEffect,以便在每次更改时将其发射,如果你离开它[]它将会开火一次。

  useEffect(
    () => {
      window.addEventListener("scroll", handleScroll);
      return () => {
        window.removeEventListener("scroll", handleScroll);
      };
    },
    [isHeaderMoved]
  );

我想你也可以使用useRef()来做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.