I would like to do multiple fetch requests with React/JavaScript, I have the following attempt which kind of works:
const fetchAll = async () => {
Promise.all([
await fetch('/api/...'),
await fetch('/api/...')
]).then(links => {
const response1 = links[0];
const response2 = links[1];
timeData = response1.json();
functionData = response2.json();
})
}
But I would like to do it this way, because that seems more useful. I would like to use useEffect and useState and load the data of the different APIs in different arrays in useState if that's possible. Here is an example:
const [data, setData] = useState([]);
useEffect(() => {
fetch("/api/..")
.then((response) => response.json())
.then((r) => {
setData(r);
});
}, []);
Is there a way to do this for multiple requests and save the data in different arrays so I can access them later on?
This can be done nicely by
For example, create some helper functions in some module
// fetch-helpers.js
// performs a request and resolves with JSON
export const fetchJson = async (url, init = {}) => {
const res = await fetch(url, init);
if (!res.ok) {
throw new Error(`${res.status}: ${await res.text()}`);
}
return res.json();
};
// get JSON from multiple URLs and pass to setters
export const fetchAndSetAll = async (collection) => {
// fetch all data first
const allData = await Promise.all(
collection.map(({ url, init }) => fetchJson(url, init))
);
// iterate setters and pass in data
collection.forEach(({ setter }, i) => {
setter(allData[i]);
});
};
and in your component...
import { useEffect, useState } from "react";
import { fetchAndSetAll } from "./fetch-helpers";
export const MyComponent = () => {
// initialise state to match the API response data types
const [timeData, setTimeData] = useState([]);
const [functionData, setFunctionData] = useState([]);
useEffect(() => {
fetchAndSetAll([
{
url: "/api/...",
setter: setTimeData,
},
{
url: "/api/...",
setter: setFunctionData,
},
]).catch(console.error);
}, []);
return <>{/* ... */}</>;
};