Table of Contents
What is setTimeout function?
setTimeout
function is used to execute a block of code after a specified period.
setTimeout
accepts 2 parameters. The first one is the callback function to be called after the time has expired.
The second is the delay in milliseconds after which the callback needs to be called.
The second parameter is optional, if not passed the callback will be called immediately (in the next event cycle).
Example:
1setTimeout(() => {2 console.log("This will appear after 3 seconds")3}, 3000)
Using setTimeout in React hooks
We can execute setTimeout inside useEffect hook as shown below:
1import { useEffect } from "react"23function App() {4 useEffect(() => {5 setTimeout(() => {6 console.log("This will appear after 3 seconds")7 })8 }, [])910 return <div className="App"></div>11}1213export default App
If you run the react application and open the browser console, you may see the message being displayed twice after 3 seconds. This is because, since React v18, using StrictMode in the development environment will mount, unmount, and again mount the application. Hence the useEffect will be called twice.
Clearing the timeout
Say the component got unmounted before the timeout has expired, then executing the callback may not make sense.
In such cases, we can clear the timeout by calling clearTimeout
and passing it the identifier returned while creating the timeout.
1import { useEffect } from "react"23function App() {4 useEffect(() => {5 const timeOutId = setTimeout(() => {6 console.log("This will appear after 3 seconds")7 })8 return () => {9 clearTimeout(timeOutId)10 }11 }, [])1213 return <div className="App"></div>14}1516export default App
Now if you see the console, you will see the message only once since we are clearing the previous timeout during unmounting of the component.
Setting the state inside setTimeout
If you need to call setState
inside the timeout, you can do so using the following code:
1import { useEffect, useState } from "react"23function App() {4 const [counter, setCounter] = useState(0)5 useEffect(() => {6 let timeOutId = setTimeout(() => {7 setCounter(oldCounter => {8 return oldCounter + 19 })10 }, 3000)1112 return () => {13 clearTimeout(timeOutId)14 }15 }, [])1617 return <div className="App">{counter}</div>18}1920export default App
If you run the code, you will see that the counter changes from 0 to 1 after 3 seconds.
Do follow me on twitter where I post developer insights more often!