When you use the setInterval
function in React, it is essential to use the clearInterval
function to remove the interval timer upon component unmount.
The below example sets a timer for 10 seconds. The alert message stays red until the 10 seconds timer is up and then turns green.
The initial time is set in the state variable
const [timer, setTimer] = useState(10)
Then we decrement this number by one every second. This function does the decrements. Since we use this method inside the useEffect
hook, I wrapped the method in useCallback
to prevent unnecessary re-renders.
const decrementTimer = useCallback(() => {
setTimer((oldTimer) => oldTimer-1)
},[])
The setInterval
method is called in the useEffect
hook.
const timeoutFunction = setInterval(decrementTimer, 1000)
return () => clearInterval(timeoutFunction);
The timeoutFunction
variable is to clear the setInterval
function upon the component unmount.
We want to stop the timer at 0. Otherwise, the countdown happens as long as the component stays mounted until it unmounts.
if(timer <= 0){
return
}
The above code in the useEffect
function makes the useEffect
return when the timer reaches 0 or below. That triggers clearInterval
on the timeoutFunction
variable referencing to the setInterval(decrementTimer, 1000)
function.
import { useCallback, useEffect, useState } from "react"
import { Alert } from "react-bootstrap"
const SuccessMessage = () =>{
const [timer, setTimer] = useState(10)
const decrementTimer = useCallback(() => {
setTimer((oldTimer) => oldTimer-1)
},[])
useEffect(() => {
if(timer <= 0){
return
}
const timeoutFunction = setInterval(decrementTimer, 1000)
return () => clearInterval(timeoutFunction);
},[decrementTimer, timer])
return(
<div>
<Alert
variant={timer > 0 ? "danger" : "success"}>
This message will turn green in {timer} seconds
</Alert>
</div>
)
}
export default SuccessMessage
The useEffect
function has two dependencies, decrementTimer
, and timer
. The decrementTimer
is an external dependency on the useEffect
, and we want to execute the useEffect
hook every time the timer
variable changes.