Reputation: 802
I am getting data in useEffect
and looping through it to add additional data.
I want to do some calculations on it after all data being added to results
, I make the calculations inside if (response.data.next)
but after that inside then
when I try to access data it prints old data.
How can I make make sure all data added then be able to use it in then
?
const [results, setResults] = useState([]);
useEffect(() => {
async function handleAPIRequest(url) {
return await axios
.get(url)
.then(async (response) => {
await setResults((results) => [...results, ...response.data.results]);
if (response.data.next) {
await handleAPIRequest(response.data.next);
}
return results;
})
.then(async () => {
// this is where I want to use results
console.log("resultss: ", results);
});
}
handleAPIRequest(url)
}, []);
Upvotes: 0
Views: 35
Reputation: 4469
You should change your code in the following way:
const [results, setResults] = useState([]);
useEffect(() => {
const handleAPIRequest = async url => {
const lastResult = await axios.get(url);
setResults([...results, ...lastResult.data.results]);
const toLogResults = [...results, ...lastResult.data.results];
if(response.data.next) {
await handleAPIRequest(response.data.next);
} else {
console.log("The final results are", toLogResults);
}
}
handleAPIRequest(url)
}, []);
The main problem is that results
in lines following setResults()
are not updated immediately, so the value is the old one.
The toLogResults
is used just to display the actual result, it is not needed.
Upvotes: 0
Reputation: 10382
I would suggest to keep consistency between async/await or chaining promises. your approach can cause multiple setResults
, not sure if that's what you desire. Below, I offer a solution that might suit your needs:
useEffect(() => {
async function handleAPIRequest(url, currentResults = []) {
try {
const response = await axios.get(url)
const nextResults = [...currentResults, ...response.data.results];
if (response.data.next) {
return await handleAPIRequest(response.data.next, nextResults);
}
return nextResults;
} catch (error) {
throw error;
}
}
try {
const finalResults = await handleAPIRequest(url);
setResults(results => [...results, ...finalResults]);
} catch (error) {
// here you can handle error response
console.log(error);
}
}, []);
// to do something after results state is updated use another use effect to accomplish that
useEffect(() => {
// do something on updated results state
}, [JSON.stringify(results)]);
Upvotes: 1