Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

SetTimeout Firing Twice

This is the React code that I have for a page:

function ExportViewerPage(): JSX.Element {
  const [hasPrinted, setHasPrinted] = useState(false);

  if (!hasPrinted) {
    setHasPrinted(true);
    console.log("Inside if loop, hasPrinted: ", hasPrinted)
    setTimeout(() => {
      console.log("Executing setTimeout: ", hasPrinted)
    });
  }

  return (<div>Page</div>)
}

export default ExportViewerPage;

Ultimately, the code should execute the code in the setTimeout function once. However, it actually executes twice as seen in the console here:

Inside if loop, hasPrinted:  false
Executing setTimeout:  false
Executing setTimeout:  false

The weird thing is that the console log immediately before the setTimeout function only executes once, so the setTimeout is not being called twice and hasPrinted is getting set correctly. This is happening on both Chrome and Firefox.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I did notice that if I turn reactStrictMode off in the next.config.js file, the setTimeout will only fire once. But I am still confused as to why the setTimeout is firing twice with reactStrictMode on but the console log immediately above it is only logging once.

>Solution :

This behavior is caused by React’s strict mode, which can execute some code twice in development mode to detect potential issues. One of the effects of strict mode is that some side-effects may be executed twice, including some lifecycle methods like componentDidMount.

In your case, the setTimeout function is a side-effect that is being executed twice because it is inside the component body. One possible solution would be to move it into a useEffect hook with an empty dependency array, so that it only gets executed once when the component mounts:

function ExportViewerPage(): JSX.Element {
  const [hasPrinted, setHasPrinted] = useState(false);

  useEffect(() => {
    if (!hasPrinted) {
      setHasPrinted(true);
      console.log("Inside useEffect, hasPrinted: ", hasPrinted)
      setTimeout(() => {
        console.log("Executing setTimeout: ", hasPrinted)
      });
    }
  }, []);

  return (<div>Page</div>)
}

export default ExportViewerPage;

This code will only execute the setTimeout function once when the component mounts, regardless of whether the strict mode is enabled or not.

https://react.dev/reference/react/StrictMode#fixing-bugs-found-by-double-rendering-in-development

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading