反应setTimeout和clearTimeout

时间:2020-04-21 10:31:11

标签: javascript reactjs react-hooks

最近我正在使用React创建一个网站,我发现我经常使用很多'setTimeOut()',并且我知道从React文档中有时您需要在卸载组件时清理一些东西(说实话,我对此清理工作还不完全了解),显然,最近我看到一则帖子说'setTimeOut()'也需要清理,但是我该如何清理在'useEffect()'中调用的函数在函数内部使用“ setTimeOut()”?

这是我的代码:

  useEffect(() => {
    createContent();
    handleMobileContainerView();
  });


  const createContent = () => {
    if (contentCompShowStatus) {
      for (let key in btnStatus) {
        if (btnStatus.hasOwnProperty(key)) {
          if (btnStatus[key] === true) {
            if (key === 'aboutBtn') {
               delayContent('about-contents');
            } else if (key === 'skillsBtn') {
               delayContent('skills-contents');
            } else if (key === 'projectsBtn') {
               delayContent('projects-contents');
            }
          }
        }
      }
    }
  };


  const delayContent = (content) => {
    if (firstTime) {
      setTimeout(() => {
        setCurrentContent(content);
        setFirstTime(false);
      }, 200);
    } else if (!firstTime) {
      setTimeout(() => {
        setCurrentContent(content);
      }, 450);
    }
  };

如您在上面的代码中所见,“ createContent()”位于“ useEffect()”中,并调用使用“ setTimeout()”的函数名称“ delayContent()”。

我需要对这种情况进行清理吗?

如何清理这种情况? (在函数内部使用'setTimeOut()'并在'useEffect()'中调用的函数)

2 个答案:

答案 0 :(得分:1)

您可以使用useEffect返回一个函数,该函数应负责清理setTimouts和setIntervals。例如,

useEffect(() => {
  const timer = setTimeout(someFunc, 100);
  return () => clearTimeout(timer);
});

要清除setTimout,请对setInterval使用clearTimeout和clearInterval。 Documentation

就您的代码而言,

  useEffect(() => {
    const timers = createContent();
    handleMobileContainerView();
    return () => timers.forEach(timer => window.clearTimeout(timer));
  });

  const createContent = () => {
    let timers = [];
    if (contentCompShowStatus) {
      for (let key in btnStatus) {
        if (btnStatus.hasOwnProperty(key)) {
          if (btnStatus[key] === true) {
            if (key === 'aboutBtn') {
               timers.push(delayContent('about-contents'));
            } else if (key === 'skillsBtn') {
               timers.push(delayContent('skills-contents'));
            } else if (key === 'projectsBtn') {
               timers.push(delayContent('projects-contents'));
            }
          }
        }
      }
    }
    return timers;
  };


  const delayContent = (content) => {
    let timer;
    if (firstTime) {
      timer = setTimeout(() => {
        setCurrentContent(content);
        setFirstTime(false);
      }, 200);
    } else if (!firstTime) {
      timer = setTimeout(() => {
        setCurrentContent(content);
      }, 450);
    }
    return timer;
  };

答案 1 :(得分:1)

您可以在创建超时时返回timerId。在unmount上,您可以使用return function中的useEffect进行清洁。

卸载:

  useEffect(() => {
    const timerId = createContent();
    handleMobileContainerView();
    return () => {
      clearTimeout(timerId);
    };
  }, []);

返回TimerId:

  const delayContent = (content) => {
    let timerId;
    if (firstTime) {
      timerId = setTimeout(() => {
        setCurrentContent(content);
        setFirstTime(false);
      }, 200);
    } else if (!firstTime) {
      timerId = setTimeout(() => {
        setCurrentContent(content);
      }, 450);
    }
    return timerId;
  };

//所有代码:

function A() {
  useEffect(() => {
    const timerId = createContent();
    handleMobileContainerView();
    return () => {
      clearTimeout(timerId);
    };
  }, []);
  const createContent = () => {
    if (contentCompShowStatus) {
      for (let key in btnStatus) {
        if (btnStatus.hasOwnProperty(key)) {
          if (btnStatus[key] === true) {
            if (key === "aboutBtn") {
              return delayContent("about-contents");
            } else if (key === "skillsBtn") {
              return delayContent("skills-contents");
            } else if (key === "projectsBtn") {
              return delayContent("projects-contents");
            }
          }
        }
      }
    }
  };

  const delayContent = (content) => {
    let timerId;
    if (firstTime) {
      timerId = setTimeout(() => {
        setCurrentContent(content);
        setFirstTime(false);
      }, 200);
    } else if (!firstTime) {
      timerId = setTimeout(() => {
        setCurrentContent(content);
      }, 450);
    }
    return timerId;
  };
}