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.
CodePudding user response:
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])