【问题标题】:setInterval does not in React Functional ComponentsetInterval 不在 React 功能组件中
【发布时间】:2020-07-06 07:58:01
【问题描述】:

我做了一个 React 组件,它可以在必要时将内容滚动到页面顶部,如果你看一下代码沙箱示例,如果向下滚动一点会显示“GO Top”按钮,如果单击它,页面将滚动到顶部,如果您尝试向下滚动,它总是会将您带到页面顶部。原因是没有清除计时器,因为 intervalId 始终为空。具体来说,如果您查看第 20 行,intervalId 始终为空,我想这可能与关闭有关,但我无法修复它。请帮忙。

谢谢!

代码贴在下面,codesanbox example is here

import React from "react";

const GoTop = ({ scrollStepInPx, delayInMs }) => {
  const [intervalId, setIntervalId] = React.useState(null);
  const [position, setPosition] = React.useState(false);

  React.useEffect(() => {
    document.addEventListener("scroll", () => {
      if (window.scrollY > 200) {
        setPosition(true);
      } else {
        setPosition(false);
      }
    });
    window.scrollTo(0, 0);
  }, []);

  const onScrollStep = () => {
    if (window.pageYOffset === 0) {
      console.log(intervalId); //always null
      clearInterval(intervalId);
      return;
    }
    window.scroll(0, window.pageYOffset - scrollStepInPx);
  };

  const scrollToTop = () => {
    const id = setInterval(onScrollStep, delayInMs);
    setIntervalId(() => id);
  };

  const renderGoTopIcon = () => {
    if (position) {
      return (
        <button className="go-top" onClick={scrollToTop} type="button">
          Go Top
        </button>
      );
    }
    return null;
  };

  return <>{renderGoTopIcon()}</>;
};

export default GoTop;

【问题讨论】:

    标签: reactjs react-hooks setinterval


    【解决方案1】:

    我让它像这样工作,这篇文章有帮助。 https://dmitripavlutin.com/react-hooks-stale-closures/

    import React from "react";
    
    const GoTop = ({ scrollStepInPx, delayInMs }) => {
      const [position, setPosition] = React.useState(false);
    
      React.useEffect(() => {
        document.addEventListener("scroll", () => {
          if (window.scrollY > 200) {
            setPosition(true);
          } else {
            setPosition(false);
          }
        });
        window.scrollTo(0, 0);
      }, []);
    
      const scrollToTop = () => {
        let intervalId;
        //move the event handle here, NOT use hooked state variable intervalId
        const onScrollStep = () => {
          if (window.pageYOffset === 0) {
            clearInterval(intervalId);
            return;
          }
          window.scroll(0, window.pageYOffset - scrollStepInPx);
        };
    
        intervalId = setInterval(onScrollStep, delayInMs);
      };
    
      const renderGoTopIcon = () => {
        if (position) {
          return (
            <button className="go-top" onClick={scrollToTop} type="button">
              Go Top
            </button>
          );
        }
        return null;
      };
    
      return <>{renderGoTopIcon()}</>;
    };
    
    export default GoTop;
    

    【讨论】:

      猜你喜欢
      • 2020-11-09
      • 2020-11-29
      • 2022-01-23
      • 1970-01-01
      • 2021-10-10
      • 2021-07-12
      • 1970-01-01
      • 2019-08-06
      • 2021-06-20
      相关资源
      最近更新 更多