Why is my axios get call repeating over and over using React.useEffect?
Asked Answered
I

1

9

I am using axios on a React w/ Hooks front end to make a get request to populate my react-google-maps/api GoogleMaps Marker components using seed data in my rails backend. When I let the rails server run, the server repeatedly makes this call.

The following line causes the axios.get to be called on a loop:

 React.useEffect(() => {
        // Get Coordinates from api
        // Update Coordinates in state
        axios.get('/api/v1/coordinates.json')
        .then(response => response.data.data.map(coord => 
              setCoordinateFromApi(coord.attributes)))
        .catch(error => console.log(error))
    }, [coordinates.length]) 

This successfully populates the map but means I can't use onClick's functionality (because I presume the stack is being topped with this request?)

My index method on my CoordinatesController in Rails:

def index
  coordinates = Coordinate.all
  render json: CoordinateSerializer.new(coordinates).serialized_json
end

NB: this is my first project linking React to Rails as well as using Hooks

Irish answered 22/5, 2020 at 16:28 Comment(1)
Have you tried removing the dependency coordinates.length from the dependency array in React.useEffect? Having more code would be great to have when investigating this issue.Portwine
M
14

I would assume that you have this useState defined above:

const [coordinated, setCoordinatesFromApi] = useState([])

If it is, then this is the root cause:

React.useEffect(() => {
  axios.get(...).then(coordinates => setCoordinateFromApi(coord.attributes))
}, [coordinates.length])

By doing so, you ask React.useEffect to always call axios.get whenever coordinates.length change. Which will make this useEffect an infinite loop (because you always change the coordinates value whenever the axios request finish).

If you only want to execute it once, you should just pass an empty array on the useEffect, like this

React.useEffect(() => {
  axios.get(...).then(coordinates => setCoordinateFromApi(coord.attributes))
}, [])

That way, your axios.get will only be called once and you will no longer have infinite loop

Marmoreal answered 22/5, 2020 at 16:48 Comment(1)
Thank you for this. Accidentally used all of my API calls because I didn't pass an empty array. Smh lolYonatan

© 2022 - 2024 — McMap. All rights reserved.