Using 2 fetches, setTimeout() behaves awkwardly
Unanswered
Japanese common catfish posted this in #help-forum
Japanese common catfishOP
So I want to build a frontend for an API that returns system metrics. The API is written in Rust and provides the data like CPU and RAM usage. I am using Next.JS rewrites to redirect them to avoid CORS issues. When fetching the CPU data alone, it works fine and the shadcn chart is running smoothly, however as soon as I start fetching the RAM info as well, the chart does not update smoothly. I tried putting the fetch for the RAM in it's own useEffect to no avail.
If you need more code or details, let me know. I also attached a video of the behavior with and without the 2nd fetch. (Ignore the glitching, my recording program is unstable)
I know that this might the worst way to do it but it's a school project and nothing production ready
const [cpuData, setCpuData] = useState({ cpu_count: 1, cpu_usage: [0.0] });
const [ramData, setRamData] = useState({ ram_used: 0, ram_available: 1 });
useEffect(() => {
setTimeout(() => {
fetch("/api/metrics/cpu")
.then((response) => response.json())
.then((cpu) => {
setCpuData(cpu);
})
.catch((err) => console.error("Fetch error:", err));
fetch("/api/metrics/ram")
.then((response) => response.json())
.then((ram) => {
setRamData(ram);
})
.catch((err) => console.error("Fetch error:", err));
}, 1000);
}, [cpuData, ramData]);
If you need more code or details, let me know. I also attached a video of the behavior with and without the 2nd fetch. (Ignore the glitching, my recording program is unstable)
I know that this might the worst way to do it but it's a school project and nothing production ready
2 Replies
Asian black bear
You are experiencing a race condition between updating state yourself, React batching them and not necessarily updating right away and an very brittle way of polling. You should have better results by using a
setInterval
with a cleanup function so that you don't need to have the state values as dependencies. You also need to keep in mind to use AbortControllers to prevent receiving outdated updates. Having said that, don't manually implement polling in the first place. Use SWR or react-query that are robust under the hood and provide proper polling capabilities.