MrBear77
MrBear77

Reputation: 103

React setTimeout and clearTimeout

Recently I am creating a website using React and I found out that I kind of use a lot of 'setTimeOut()' and I know that from React documentation sometimes you need to clean up some things when component unmount(To be honest, I am not fully understand about this clean up thing), apparently recently I saw a posts saying that 'setTimeOut()' need to be clean up too but how do I clean up functions that I call in 'useEffect()' which I am using 'setTimeOut()' inside the function?

Here are my codes:

  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);
    }
  };

As you can see above codes, 'createContent()' is in 'useEffect()' and is calling a function name 'delayContent()' which is using 'setTimeout()'.

Do I need to do clean up with this kind of case?

How do I do clean up with this kind of case? (function inside of function which is using 'setTimeOut()' and is called in 'useEffect()')

Upvotes: 2

Views: 4229

Answers (2)

Siri
Siri

Reputation: 1126

You can use useEffect to return a function which should do the job of cleaning up of the setTimouts and setIntervals. For eg,

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

To cleanup setTimouts, use clearTimeout and clearInterval for setInterval. Documentation

As far as your code is concerned,

  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;
  };

Upvotes: 1

xdeepakv
xdeepakv

Reputation: 8125

You can return timerId while creating timeOut. And on unmount u can clean using return function of useEffect.

Unmount:

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

Return 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;
  };

// All code:

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;
  };
}

Upvotes: 1

Related Questions