Proper way to use setTimeout and setInterval in useEffect()

Proper way to use setTimeout and setInterval in useEffect()

The proper way to write a timer using setTimeout or setInterval within a useEffect hook in React involves ensuring proper cleanup to prevent memory leaks and unexpected behavior.

Cleanup Function:

The return statement within useEffect defines a cleanup function. This function is crucial for clearing the timer (using clearTimeout or clearInterval) when the component unmounts or when the dependencies change (if a dependency array is provided). This prevents the timer from continuing to run in the background after the component is no longer visible, which can lead to memory leaks and errors.

State Updates within Timers:

When updating state within a timer, especially with setInterval, use the functional update form of setState (e.g., setCount(prevCount => prevCount + 1)) to ensure you are working with the latest state value and avoid closure issues.

setTimeout (single execution after a delay)

import React, { useEffect } from 'react';

function MyComponent() {
    useEffect(() => {
        // Set the timeout
        const timerId = setTimeout(() => {
            // Your code to execute after the delay
            console.log('This runs after 3 seconds');
        }, 3000); // 3000 milliseconds = 3 seconds

        // Cleanup function to clear the timeout when the component unmounts
        return () => {
            clearTimeout(timerId);
        };
    }, []); // Empty dependency array ensures it runs only once on mount
}

setInterval (repeated execution at intervals)

import React, { useEffect, useState } from 'react';

function MyTimerComponent() {
    const [count, setCount] = useState(0);

    useEffect(() => {
        // Set the interval
        const intervalId = setInterval(() => {
            // Your code to execute repeatedly
            setCount(prevCount => prevCount + 1);
        }, 1000); // 1000 milliseconds = 1 second

        // Cleanup function to clear the interval when the component unmounts
        return () => {
            clearInterval(intervalId);
        };
    }, []); // Empty dependency array ensures it runs only once on mount

    return (
        <div>
            <p>Count: {count}</p>
        </div>
    );
}

Live demo of timer