Skip to content
Advertisement

Why is my useEffect function called only once?

I am rendering a list of Trips objects inside a FlatList. So I have a screen named Network where I have FlatList which represents each of the trips. My render method:

JavaScript

Inside my Trip component is the trip information. Trip’s name AND trip’s geo locations. From those geolocations I want to get the trip’s city and country. To do so I call expo‘s Location API inside my useEffect function, for each trip:

JavaScript

However, it seems that this function id being called only once for the very last trip, from all trips inside my FlatList. This is how my Trip.js component looks like:

JavaScript

I put so many console.logs because I wanted to be sure that I have trip.longitude and trip.latitude which, indeed, I have. What I see printed on the console:

JavaScript

And indeed on my screen I see only the very last trip’s city and country being shown.

How to make sure that my useEffect function is being called for every single trip, not just the last one?

Advertisement

Answer

Your logs show that useEffect is being called twice:

JavaScript

So it’s not the useEffect that’s the problem. The issue is that you’re never getting a return value from Location.reverseGeocodeAsync for one of your calls.

Looking in the Expo docs for Location, you can see the following warning:

Note: Geocoding is resource consuming and has to be used reasonably. Creating too many requests at a time can result in an error, so they have to be managed properly. It's also discouraged to use geocoding while the app is in the background and its results won't be shown to the user immediately.

In the iOS code for expo-location, the following line gets printed if there are too many calls: Rate limit exceeded - too many requests. If you’re seeing that line, you need to make a way to space out these requests.

reverseGeocodeAsync also takes an options argument that allows you to use Google’s location service instead ({ useGoogleMaps: true }).

So in summary, here are two things to try. You can rewrite your useEffect to explicitly catch errors in case they’re not showing up (removed logs for brevity):

JavaScript

And if you are seeing the rate limit error, you would need to build a request queue that spaces out the calls enough to avoid that.

Or you can try using Google’s service, which would be the same except for the line that calls reverseGeocodeAsync:

JavaScript
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement