简体   繁体   中英

Why does my axios call seemingly go on forever?

I'm quite new to React and I have been given a task of creating an application that finds a bunch of surfing spots along the coast and ranks them from novice to expert surfer (depending on how high the wind speeds are for each spot).

Here is a link to my application in current progress: https://lewisd1996.github.io/surferspotter/

When it loads up, you can see the spots are already loaded onto the map, however it doesn't stop the GET request and just keeps going, you can see in the chrome console "XHR finished loading: GET """. The timer is just going on forever and my laptop's fans kick into overdrive.

Am I missing something to tell it to stop once all the data has been fetched?

My SurfMap component:

import React, { Component } from 'react';
import L from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import main from '../styles/main.scss';
import SpotList from "./SpotList.js";
import axios from 'axios';

var owmApiKey = '';

var myIcon = L.icon({ //SETS UP THE PIN ICON THAT IS USED TO PLOT MARKERS ON THE MAP
    iconUrl: 'https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-512.png',
    iconSize: [41,41],
    iconAnchor: [12.5,41],
    popupAnchor: [0, -41]
});

export default class SurfMap extends Component {

    constructor() {
    super()
    this.state = {
        spots: [] //THE ARRAY THAT WILL HOLD THE LIST OF SURFING SPOTS
    }
    }

    getSpots() { //THE FUNCTION TO POPULATE THE LIST OF SPOTS USING AXIOS
        axios.get(`https://s3.eu-west-2.amazonaws.com/lpad-public-assets/software-test/all-spots.json`)
        .then(res => {
            this.setState({
                spots: res.data
            });
        });
}

    render() {
        var startPosition = [36.778259, -119.417931] //STARTING POSITION OF THE MAP
        this.getSpots(); //POPULATE THE LIST OF SURFING SPOTS
        return (

                <Map className="map" center={startPosition} zoom={5}>
                    <TileLayer
                        attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                        />
                    {this.state.spots.map (spot => //LOOP THROUGH THE LIST OF SPOTS AND CREATE A MARKER FOR EACH ONE TO BE PLOTTED ONTO THE MAP
                        <Marker position={[spot.latitude,spot.longitude]} icon={myIcon}>
                            <Popup>
                                {spot.spot_name}
                            </Popup>
                        </Marker>    
                    )}
                </Map>

        )
    }
}

You'll need to bind this in getSpots :

getSpots = () => {...```

and than call it inside componentDidMount (remove it from render):

componentDidMount() {
  this.getSpots()
}

This is happening because you are calling axios fetch method ie, getSpots() inside render() method. Which is wrong.

render() method gets called on every update. So, whenever something in that component will get updated render() method will be called and your getSports() method will be fired. Avoid doing network calls inside render()

If you want to get the data you can use componentDidMount lifecycle to call getSports() . Since, this lifecycle method gets called only once. Your network call will happen only once.

So, try this.

import React, { Component } from 'react';
import L from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import main from '../styles/main.scss';
import SpotList from "./SpotList.js";
import axios from 'axios';

var owmApiKey = '';

var myIcon = L.icon({ //SETS UP THE PIN ICON THAT IS USED TO PLOT MARKERS ON THE MAP
    iconUrl: 'https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-512.png',
    iconSize: [41,41],
    iconAnchor: [12.5,41],
    popupAnchor: [0, -41]
});

export default class SurfMap extends Component {

  constructor() {
    super()
    this.state = {
      spots: [] //THE ARRAY THAT WILL HOLD THE LIST OF SURFING SPOTS
    }
  }

  componentDidMount(){
    this.getSpots();
  }

  getSpots() { //THE FUNCTION TO POPULATE THE LIST OF SPOTS USING AXIOS
    axios.get(`https://s3.eu-west-2.amazonaws.com/lpad-public-assets/software-test/all-spots.json`)
    .then(res => {
      this.setState({
        spots: res.data
      });
    });
  }

  render() {
    var startPosition = [36.778259, -119.417931] //STARTING POSITION OF THE MAP
    return (
      <>
        {this.state.spots.length ? 
        <Map className="map" center={startPosition} zoom={5}>
            <TileLayer
                attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
            {this.state.spots.map (spot => //LOOP THROUGH THE LIST OF SPOTS AND CREATE A MARKER FOR EACH ONE TO BE PLOTTED ONTO THE MAP
                <Marker position={[spot.latitude,spot.longitude]} icon={myIcon}>
                    <Popup>
                        {spot.spot_name}
                    </Popup>
                </Marker>    
            )}
        </Map>:
        <p>loading data....</p>}
      </>
    )
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM