Почему мой топор ios зовет, казалось бы, go навсегда? - PullRequest
0 голосов
/ 01 апреля 2020

Я довольно новичок в React, и мне дали задание создать приложение, которое находит кучу мест для серфинга вдоль побережья и ранжирует их от новичка до опытного серфера (в зависимости от того, насколько высоки скорости ветра для каждого spot).

Вот ссылка на мое приложение в текущем процессе: https://lewisd1996.github.io/surferspotter/

Когда оно загружается, вы можете видеть, что пятна уже загружены на map, однако он не останавливает запрос GET и просто продолжает работу, вы можете увидеть в консоли chrome «XHR закончила загрузку: GET» «». Таймер работает вечно, и поклонники моего ноутбука начинают работать с перегрузкой.

Я что-то упускаю, чтобы сказать, что он остановится, как только все данные будут получены?

Мой компонент SurfMap:

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>

        )
    }
}

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

Это происходит потому, что вы вызываете метод ax ios fetch, т. Е. getSpots() внутри render() метода. Что не так.

render() метод вызывается при каждом обновлении. Таким образом, всякий раз, когда что-то в этом компоненте будет обновляться, будет вызываться метод render() и ваш метод getSports() будет запущен. Избегайте сетевых вызовов внутри render()

Если вы хотите получить данные, вы можете использовать componentDidMount жизненный цикл для вызова getSports(). Поскольку этот метод жизненного цикла вызывается только один раз. Ваш сетевой вызов произойдет только один раз.

Итак, попробуйте это.

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>}
      </>
    )
  }
}
1 голос
/ 01 апреля 2020

Вам нужно будет bind this в getSpots:

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

и затем вызвать его внутри componentDidMount (удалить из рендера):

componentDidMount() {
  this.getSpots()
}
...