reactjsreact-nativereact-hooks

Can't access state in functional component in React Native


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.


Solution

  • 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])