ReactJS useInterval Custom Hook
Last Updated :
25 Jul, 2024
JavaScript setInterval() repeatedly executes a function with a fixed time delay. It can be challenging to use the setInterval method in React. For instance, if we wish to update the delay parameter, we might have to deal with a lot of life cycle methods. To avoid this hassle, we can use a custom useInterval hook.
The useInterval hook implements the setInterval method in a declarative manner. By combining the setInterval and clearInterval methods, the useInterval hook sets up an interval and then clears it upon unmounting. We can simply declare an interval with a delay. The arguments for the useInterval hooks can be dynamic. This enables us to have a dynamically adjusted delay without having to worry about the start or end of an interval.
In terms of usage, useInterval resembles setInterval quite a bit:
Syntax:
useInterval(() => {
// func
}, delay);
React useInterval Hook accepts a function and a delay where,
- func: It is the function that executes repeatedly after a delay.
- delay: The delay is the time between two successive executions of the function.
Note: The arguments are dynamic, unlike those in the setInterval method.
Let’s look at an example of how to use the useInterval custom hook in React:
Approach: We will create a counter with a dynamically adjustable delay using the useInterval custom hook.
Implementation and Setup for Creating React Application:
Step 1: Make a project directory, head over to the terminal, and create a react app named counter using the following command:
npx create-react-app counter
After the counter app is created, switch to the new folder counter by typing the command below:
cd counter
Step 2: Modify Your project structure. Add a useInterval.js file in the src folder. We will modify the folder and keep the files we need for this example. Now, make sure your file structure looks like this:

Final Project Directory
Step 3: Include the following code in your index.html file, located in the public folder of your project directory.
File name: index.html
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description"
content="Web site created using create-react-app" />
<title>Counter App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Step 4: Creating the useInterval custom hook. In the useInterval.js file, we will write a function to create a custom useInterval hook which we can use in our counter application.
- The useInterval function takes in a callback function and a delay as arguments.
- This delay is not a hardcoded number and will be a dynamic parameter.
- We will use the useRef() hook to create a ref for the callback function.
- The useEffect hook cleans up the previous effects, but the setInterval method still references the old state since we do not reset the time.
- Therefore, we create a savedCallback as a mutable variable that persists between the renders and keeps track of the previous callbacks.
- We will save the callback as savedCallback.current.
- We can access this value when we set up an interval.
- We will pass in the delay as a dependency of the useEffect since it changes between renders.
- Therefore, the counter resets whenever the delay time is adjusted.
File name: useInterval.js
JavaScript
import React, { useState, useEffect, useRef } from 'react';
// creating the custom useInterval hook
export function useInterval(callback, delay) {
// Creating a ref
const savedCallback = useRef();
// To remember the latest callback .
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// combining the setInterval and
//clearInterval methods based on delay.
useEffect(() => {
function func() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(func, delay);
return () => clearInterval(id);
}
}, [delay]);
}
Step 5: Creating the counter component.
- We will use the useState and useInterval custom hooks to implement the counter.
- We will pass in the logic and the delay argument inside our custom useInterval hook.
- We will have a button to toggle play or pause the counter.
- We will enter the delay time as the input field and click on the play button.
- The delay will have a null value to pause the counter.
File name: App.js
JavaScript
import './App.css';
import { useState } from 'react'
//Import the custom hook
import { useInterval } from './useInterval'
export default function App() {
// The counter
const [count, setCount] = useState(0)
// Updating the delay dynamically
const [delay, setDelay] = useState()
// Toggle play pause the counter
const [isPlaying, setPlaying] = useState(false)
useInterval(
() => {
//counter function
setCount(count + 1)
},
// Passing in the delay parameter. null stops the counter.
isPlaying ? delay : null,
)
const handleChange = (e) => {
setDelay(e.target.value)
}
return (
<>
<div className='counterStyle'>
<h1>Let's begin counting!</h1>
<h1>{count}</h1>
<button className='btn' onClick={() =>
setPlaying(!isPlaying)}>
{isPlaying ?
'Pause⏸' :
'Play ▶'}
</button>
<p>
<label htmlFor="delay">Delay: </label>
<input
type="text"
name="delay"
onChange={handleChange}
value={delay}
placeholder='Enter delay time'
/>
</p>
</div>
</>
)
}
Step 6: Add the following code to App.css to style the counter application.
File name: App.css
CSS
.counterStyle {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 2px solid darkGreen;
margin: 2rem;
}
.btn {
background-color: darkgreen;
color: white;
border-radius: 10px;
font-size: 1rem;
padding: 10px;
}
Step 7: Add the following code in the index.js file. The index.js file serves as the main entry point, and inside it, the App.js file is rendered at the root ID of the DOM.
File name: index.js
JavaScript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Step to run the application: Run our application by using the following command:
npm start
Output: By default, the React project will run on port 3000. You can access it at localhost:3000 on your browser. You can start the counter by entering the delay time in milliseconds and clicking on the play button.
Similar Reads
ReactJS useLocalStorage Custom Hook
useLocalStorage hook makes it easy. It creates a stateful value for localStorage and gives us a function to update that value like useState. In our projects, we frequently use localStorage and state but it's a bit tricky to work localStorage's value with the state. Syntax:  const [ count, setCount
3 min read
ReactJs useDebugValue Hook
React useDebugValue Hook is introduced for the ReactJs versions above 18. React useDebugValue Hook helps developers debug custom hooks in React Developer Tools by adding additional information and labels to those hooks. Prerequisite:ReactJSReact Developer ToolsReact HooksReact Custom HooksApproach:T
2 min read
ReactJS useId Hook
React useId Hook is introduced for the ReactJS versions above 18. This hook generates unique IDs i.e, returns a string that is stable across both the server and the client sides. Prerequisite: Introduction and installation of ReactJSReact Hooks Syntax: const id = useId() Creating React Application:
3 min read
React Custom Hooks
In React, components often share similar logic, such as fetching data or handling form inputs. Instead of repeating this logic across multiple components, we can extract it into a custom hook. But what exactly are custom hooks, and how do they help? What Are Custom Hooks?A custom hook is a JavaScrip
6 min read
ReactJS useUndoState hook
The useUndoState hook is a custom hook provided by the Rooks package for React. It is similar to the useState hook in addition to undo functionality. Arguments: initialValue: It is of the type boolean that describes the initial value of the state. Its default value is false.Options: It is of the typ
2 min read
ReactJS useRef Hook
The useRef Hook is a built-in React Hook that returns a mutable reference object (ref) that persists across renders. Unlike state variables, updating a ref does not trigger a component re-render. Syntax const refContainer = useRef(initialValue);useRef returns an object { current: initialValue }.The
3 min read
ReactJS useSelect hook
The useSelect is a custom hook provided by the Rooks package for React. It is a list selection hook that helps select values from a list. Arguments: list: It is of the type array which describes the list of items for the selection. The default value is undefined.initialIndex -It is of the type numbe
2 min read
ReactJS useParams Hook
In ReactJS, when building single-page applications (SPAs) with dynamic routing, you often need to access dynamic data from the URL. For example, in a blog application, the URL will change depending on the post being viewed, like /post/:id. The useParams hook, provided by the react-router-dom package
3 min read
ReactJS useReducer Hook
The useReducer hook is an alternative to the useState hook that is preferred when you have complex state logic. It is useful when the state transitions depend on previous state values or when you need to handle actions that can update the state differently. Syntax const [state, dispatch] = useReduce
5 min read
ReactJS useMemo Hook
The useMemo Hook is a built-in React Hook that helps optimize performance by memoizing the result of a computation and reusing it unless its dependencies change. This prevents expensive computations from being re-executed unnecessarily during component re-renders. Syntax const memoizedValue = useMem
3 min read