useSetInterval react hook — easy way to call a function every n seconds

Anna Vlasenko
2 min readOct 25, 2020
Photo by Lukas Blazek on Unsplash

Hello folks, today we are going to create a new custom hook that implements setInterval behavior and calls a function every n seconds. As an example the first way we just add a random number to the state, the second one we update the chart every n seconds, it is a very common case in a real application when we receive new data from the backend and have to display it with some interval.

React hook is just a function, and we have to name it this use at the begging. For example, we have an array, we want to add a random number to it every three seconds and display it. We want useSetInterval custom hook takes callback function and milliseconds. Also, you can also see a helper function generateKey that generates a unique key.

import React, {useState} from 'react'const arr = [1,3,5,5]const SetInterval = () => {const [fields, setFields] = useState(arr);const generateKey = (pre) => {
return `${ pre }_${ new Date().getTime() }`;
}
useSetInterval(() => setFields([…fields, Math.floor(Math.random() * 100)]), 3000)//return (
<div>
{fields.map(field => <div key={generateKey(field)}>
{field}
</div>)}
</div>
)
}
export default SetInterval;

Now let's create useSetInterval function

import {useRef, useEffect} from ‘react’;export const useSetInterval = (cb, time) => {   const cbRef = useRef(null);   useEffect(() => {
cbRef.current = cb
})
useEffect(() => {
const interval = setInterval(() => cbRef.current(), time);
return () => clearInterval(interval)
}, [time])
}

Here we create a reference to the callback function because we don't want the callback function was recreated every time useSetInterval function executed. Because we are working with side effects we have to use useEffect. In every execution of useSetInterval callback function will be assigned to the current value of useRef. Then in the next useEffect we create setInterval, pass callback function, and time we receive in props, also on unmount we unsubscribe setInterval. Link to the sandbox.

For updating data in the chart, we are going to use the same useSetInterval hook and library recharts.

import React, { useState } from "react";
import { LineChart, Line, XAxis, YAxis, CartesianGrid } from "recharts";
import { useSetInterval } from "./hooks/useSetInterval";
const Chart = ({fetchedData}) => {const [chartData, setChartData] = useState({fetchedData});const generateRandomValue = (upToNum) => {
return Math.floor(Math.random() * upToNum);
};
const updateData = (_chartData) => {
setChartData([…_chartData,{
name: `Page ${generateRandomValue(500)}`,
uv: generateRandomValue(500),
pv: generateRandomValue(500),
amt: generateRandomValue(500)
}]);
};
useSetInterval(() => updateData(chartData), 3000);return (
<div>
<LineChart width={700} height={500} data={chartData}
<CartesianGrid strokeDasharray=”3 3" />
<XAxis dataKey=”name” />
<YAxis />
<Line type=”monotone” dataKey=”pv” stroke=”#8884d8" strokeWidth={2} />
</LineChart>
</div>
);
}
export default Chart;

Link to sandbox example.

--

--