React Google Maps не отображает маркеры последовательно

У меня есть следующий код для визуализации нескольких маркеров на карте React Google Maps, и маркеры не всегда отображаются. Если я закомментирую информацию для тактов 1 и 2, сохраню и раскомментирую эту информацию, маркеры будут отображать 80% времени. Если я жестко закодирую только текущее местоположение, маркер будет отображаться всегда. Понятия не имею, что я здесь делаю не так, скорее всего, это ошибка ID-10-T с моей стороны. Заранее благодарим за любую помощь в этом вопросе.

/* global google */

import React from "react"
import { compose, withProps, withStateHandlers } from "recompose"
import {
    withScriptjs,
    withGoogleMap,
    GoogleMap,
    Marker,
    InfoWindow,
} from "react-google-maps"

const MyMapComponent = compose(
    withProps({
        googleMapURL: "https://maps.googleapis.com/maps/api/js?key=[api key goes here]&v=3.exp&libraries=geometry,drawing,places",
        loadingElement: <div style={{ height: `100%` }} />,
        containerElement: <div style={{ height: `600px` }} />,
        mapElement: <div style={{ height: `75vh`, width: '50vw' }} />,
    }),
    withStateHandlers(() => ({
        isOpen: false,
    }), {
            onToggleOpen: ({ isOpen }) => () => ({
                isOpen: !isOpen,
            })
        }),
    withScriptjs,
    withGoogleMap
)((props) =>
    <GoogleMap
        zoom={15}
        center={props.currentLocation}
    >
        {props.markerList.map((marker, index) => {
            return (
                <Marker
                    position={{
                        lat: marker.lat,
                        lng: marker.lng
                    }}
                    onClick={props.onToggleOpen}
                    title={marker.name}
                    key={marker.name}
                >
                    {props.isOpen && <InfoWindow onCloseClick={props.onToggleOpen}>
                        <div>
                            <h3>Info Window</h3>
                            <h4>Testing</h4>
                        </div>
                    </InfoWindow>}
                </Marker>
            )
        })};

    </GoogleMap>
);

const markers = [
    {
        lat: 38.3332416,
        lng: -95.63961839999999,
        name: "bar 1"
    },
    {
        lat: 38.0332416,
        lng: -95.63971639999999,
        name: "bar 2"
    }
];

class MyFancyComponent extends React.PureComponent {
    state = {
        isMarkerShown: false,
    }


    componentWillMount() {
        this.getGeoLocation()
    }

    getGeoLocation = () => {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(
                position => {
                    this.setState({
                        currentLatLng: {
                            lat: position.coords.latitude,
                            lng: position.coords.longitude,
                            name: "current location"
                        }
                    })
                    markers.unshift(this.state.currentLatLng);
                }
            )
        } else {
            error => console.log(error)
        }
    }

    render() {
        return (
            <MyMapComponent
                currentLocation={this.state.currentLatLng}
                markerList={markers}
            />
        )
    }
}

export default MyFancyComponent;

person John Coleman    schedule 01.09.2018    source источник


Ответы (1)


Дело в том, что позиция определяется (выполняется функция обратного вызова Geolocation.getCurrentPosition()) компонент MyMapComponent уже может быть отрисован, что, скорее всего, является причиной того, что маркеры отображаются непоследовательно.

Чтобы устранить такое поведение, можно рассмотреть следующее решение.

Поскольку MyFancyComponent уже является компонентом с отслеживанием состояния, я бы предложил ввести состояние markers и установить начальные значения следующим образом:

class MyFancyComponent extends React.PureComponent {
  state = {
    isMarkerShown: false,
    markers: markers
  };

  //...
}

Затем, как только текущее местоположение определено, состояние может быть обновлено следующим образом:

getGeoLocation = () => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(position => {

        let latLng = {
            lat: position.coords.latitude,
            lng: position.coords.longitude,
            name: "current location"
          };

        this.setState( prevState => ({
          currentLatLng: latLng,
          markers: [latLng,...prevState.markers]
        }));
      });
    } else {
      error => console.log(error);
    }
  };

и, наконец, передан компоненту MyMapComponent в качестве реквизита:

<MyMapComponent
        currentLocation={this.state.currentLatLng}
        markerList={this.state.markers}
      /> 
person Vadim Gremyachev    schedule 08.09.2018