When trying to asynchronously make two API calls, my useState()
for the second API call is not updating on the page until the page re-renders. I am trying to check if the page is loading before rendering with isLoading
.
I’ve tried a few different promise/asynchronous approaches – even creating my own unoptimized version of a promise with setTimeout()
isLoading
const [isLoading, setIsLoading] = useState(false);
Api Calls
useEffect(() => {
setIsLoading(true);
(async () => {
await axios.get(`http://localhost:4242/player/${id}`).then((res) => {
const data = res.data;
setPlayer({ ...data });
});
await axios
.get(`http://localhost:4242/team/${player.team_ID}`)
.then((res) => {
const data = res.data;
setTeam({ ...data });
setIsLoading(false);
});
})();
}, []);
Render
<>
<Navbar/>
{isLoading && <Spinner/>}
{player && team && <Player/>}
<LoginWidget/>
<Footer/>
</>
Edit: I was able to fix this issue by using response data from the first API call instead of trying to access the useState()
variable. I also switched this to a trycatch.
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
try {
const { data: playerRes } = await axios.get(
`http://localhost:4242/player/${id}`
);
setPlayer({ ...playerRes });
const { data: teamRes } = await axios.get(
`http://localhost:4242/team/${playerRes.team_ID}`
);
setTeam({ ...teamRes });
} catch (err) {
console.log(err);
}
setIsLoading(false);
};
fetchData();
}, []);
2
Answers
Without a reproducible example, it is tricky to say why this is happening. Maybe it’s because
isLoading
is set tofalse
only after the second API call completes, which might not sync well with the initial render (or re-renders) of the React component.Either way, as the two API calls don’t depend on each other, it would be better to use
Promise.all
to fire them off at the same time and then proceed only when both have completed.This is how I would do it:
Since you’re using await, you can also try the following:
useEffect(() => {
}, []);