I'm currently trying to build an app in React Native. Unfortunately, I'm having a hard time understanding the state management in functional components.
The fetch resolves successfully and gives me an array of activities and I store them in the component's state. But after that I want to make more fetches regarding these activities and for that i need to know each activities' ID, so I have to access the state. This doesn't work though, as there's only an empty array printed to the console from the last log. From the printed timestamps I can see that everything executes in the desired order and I can easily access the state in other places and get the full array of activities, but why isn't it working here?
Here's the code:
const [activities, setActivities] = useState([]);
async function getActivites(cred){
const zeroLevel = Date.now();
fetch(`https://www.strava.com/api/v3/athlete/activities?access_token=${cred.access_token}`)
.then((res) => res.json())
.then((data) => {
for (const element of data) {
setActivities(oldActivities => [... oldActivities, element])
console.log(Date.now() - zeroLevel)
}
console.log('for-loop finished', Date.now() - zeroLevel)
})
.then(() => console.log(Date.now() - zeroLevel))
.then(() => console.log(activities))
}
I already tried to store the array in another object to make it more easily accessible, but I'm almost certain there's an easier way.
If data
is an array, you don't need to iterate over it, you can just set the activites with data, instead of looping over it:
.then((data) => {
setActivities(data)
console.log('fetch finished', Date.now() - zeroLevel)
return data
})
.then((data) => {
data.map(activity => // do the fetch on each activity)
}
Or if you want to base the chained fetch on the state, then you can manually observe the change like this:
.then((data) => {
setActivities(data)
console.log('fetch finished', Date.now() - zeroLevel)
})
useEffect(() => {
activities.map(activity =>// do the fetch on each activity)
},[activities])