.map () отображает только последний элемент из массива - PullRequest
0 голосов
/ 28 сентября 2018

Я хочу использовать Citybik.es API (http://api.citybik.es/) для отображения данных на карте Leaflet.

На данный момент код показывает только последний элемент из bikeData.map(), внутри функции рендеринга.

enter image description here

console.log(data) показывает каждый повторяющийся элемент из bikeData.map(), но отображает только последний элемент.

enter image description here

Я ищу что-то вроде этого.

Что мне не хватает?

Ответ выглядит примерно такэто:

{
  "networks": [
  {
    "company": [
      "Bike U Sp. z o.o."
    ], 
    "href": "/v2/networks/bbbike", 
    "id": "bbbike", 
    "location": {
      "city": "Bielsko-Bia\u0142a", 
      "country": "PL", 
      "latitude": 49.8225, 
      "longitude": 19.044444
    }, 
    "name": "BBBike"
  }, 
  {
    "company": [
      "PBSC", 
      "Alta Bicycle Share, Inc"
    ], 
    "href": "/v2/networks/melbourne-bike-share", 
    "id": "melbourne-bike-share", 
    "location": {
      "city": "Melbourne", 
      "country": "AU", 
      "latitude": -37.814107, 
      "longitude": 144.96328
    }, 
    "name": "Melbourne Bike Share"
  }
}

Вот код JavaScript:

import React, { Component } from 'react';
import L from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';

// code for map marker icon
var myIcon = L.icon({
    iconUrl: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=',
    iconSize: [25, 41],
    iconAnchor: [12.5, 41],
    popupAnchor: [0, -41]
});

class App extends Component {
    state = {
        location: {
            lat: 51.505,
            lng: -0.09,
        },
        bikeData: [],
        zoom: 2,
    }

    //lifecycle method to get the bike information
    componentDidMount() {

        fetch('https://api.citybik.es/v2/networks')
            .then(res => res.json())
            .then(response => {
                const networkData = response.networks;
                networkData.map((data) => {
                    console.log(data)
                    this.setState({
                        bikeData: [data]
                    });
                })
            })
    }


    render() {
        const position = [this.state.location.lat, this.state.location.lng]
        const bikeData = this.state.bikeData;
        return (
            <Map className="map" center={position} zoom={this.state.zoom}>
                <TileLayer
                    attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
                {
                    bikeData && bikeData.map((data) => {
                        console.log(data)
                        return (
                            <Marker
                                icon={myIcon}
                                key={data.id}
                                position={[data.location.latitude, data.location.longitude]}>
                                <Popup>
                                    Name: {data.name} <br />
                                    Station Details: {[data.location.city, data.location.country]}
                                </Popup>
                            </Marker>
                        )
                    }) 
                }
            </Map>
        )
    }
}

ReactDOM.render(<App/>,
    document.getElementById('root')
);

Ответы [ 3 ]

0 голосов
/ 28 сентября 2018

Попробуйте это:

 componentDidMount() {
    fetch('https://api.citybik.es/v2/networks')
        .then(res => res.json())
        .then(response => {
            const networkData = response.networks; //which is currently an array
             this.setState({
                 bikeData: networkData 
             });
        })
 }
0 голосов
/ 28 сентября 2018

Вы постоянно перезаписываете элемент состояния bikeData:

fetch('https://api.citybik.es/v2/networks')
     .then(res => res.json())
     .then(response => {
         const networkData = response.networks;
         networkData.map((data) => {
             console.log(data)
             this.setState({          // ***
                 bikeData: [data]     // *** Here
             });                      // ***
         })
     })

Непонятно, почему вы вообще используете map;конечно, map - неправильный инструмент, если вы не собираетесь возвращать значение из обратного вызова и не собираетесь использовать массив, который создает map.

Не могу сказать точно, но этопохоже, что вы просто хотите использовать networkData напрямую:

fetch('https://api.citybik.es/v2/networks')
     .then(res => res.json())
     .then(response => {
         const networkData = response.networks;
         this.setState({bikeData: networkData});
     })

Обратите внимание, что я предполагаю, что вы хотите перезаписать bikeData с результатом, а не добавить к it.

Или, если вы хотите каким-то образом преобразовать эти данные, вы бы использовали результат из map:

fetch('https://api.citybik.es/v2/networks')
     .then(res => res.json())
     .then(response => {
         const networkData = response.networks;
         this.setState({
             bikeData: networkData.map((data) => {
                 return /*...do something to data...*/;
             })
         });
     })

(То же предположение.)

Чтобы добавить к bikeData, вам необходимо использовать форму обратного вызова setState:

         this.setState(({bikeData}) => ({
             bikeData: [...bikeData, ...networkData.map((data) => {
                 return /*...do something to data...*/;
             })]
         });

Такжеобратите внимание, что у вас есть ошибка в вашем fetch звонке (вы не одиноки, много людей делают это, так много я написал это в своем анемичном маленьком блоге ): Вы не проверили res.ok:

fetch('https://api.citybik.es/v2/networks')
     .then(res => {                        // ***
         if (!res.ok) {                    // ***
             throw new Error(res.status);  // ***
         }                                 // ***
     })                                    // ***
     .then(res => res.json())
     .then(response => {
         // ...
0 голосов
/ 28 сентября 2018

Вам не рекомендуется делать setState внутри цикла.Так что сделайте setState вне цикла.Также способ, которым вы помещаете данные в массив, неправильный.Попробуйте приведенное ниже решение

   const bikeDataArray = this.state.bikeData;
   networkData.map(data => {
     console.log(data)
     bikeDataArray.push(data);     
   })
   this.setState({
      bikeData: bikeDataArray
   });
...