Я создаю приложение React, в котором многие маркеры отображаются на карте реагировать-google-maps. Пользователь может фильтровать маркеры так, чтобы не все отображались одновременно. Отображение 4000 маркеров с помощью MarkerClusterer работает нормально. Для их отображения требуется разумное количество времени, а затем карта отзывчива.
Моя проблема теперь возникает, когда я пытаюсь отобразить только один или несколько маркеров после того, как рендерил 4000 раньше. Браузер зависает, и я больше ничего не могу сделать в браузере. Нет предупреждения или ошибки бесконечного цикла. Консоль не отображает ничего, что могло бы помочь мне до остановки.
Код для отображения компонента карты:
import React from 'react';
import { compose, withProps, withHandlers } from "recompose"
import { withScriptjs, withGoogleMap, GoogleMap, TrafficLayer } from "react-google-maps"
import { connect } from 'react-redux';
import MarkersList from './MarkersList';
const { MarkerClusterer } = require("react-google-maps/lib/components/addons/MarkerClusterer");
const Map = compose(
withProps({
googleMapURL: "https://maps.googleapis.com/maps/api/js?key=*******&callback=initMap",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `100vh` }} />,
mapElement: <div style={{ height: `100%` }} />
}),
withHandlers({
onMarkerClustererClick: () => (markerClusterer) => {
const clickedMarkers = markerClusterer.getMarkers()
console.log(`Current clicked markers length: ${clickedMarkers.length}`)
console.log(clickedMarkers)
}
}),
withScriptjs,
withGoogleMap
)((props) =>
<GoogleMap
defaultZoom={5.76}
defaultCenter={{ lat: 49.4299758, lng: 14.0531568 }}
mapTypeId="terrain"
fullscreenControl={false}
>
<TrafficLayer autoUpdate />
<MarkerClusterer
onClick={props.onMarkerClustererClick}
averageCenter
enableRetinalIcons
gridSize={60}
>
{props.isMarkerShown && <MarkersList/>}
</MarkerClusterer>
</GoogleMap>
);
export default connect()(Map);
Компонент MarkersList:
import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Marker, InfoWindow } from 'react-google-maps';
import { markersActionCreators } from './MarkersActions';
class MarkersList extends React.Component {
componentDidMount() {
if(this.props.markers.length === 0) {
this.props.requestMarkers();
}
}
render() {
var listComponent = this.props.displayedMarkers.map((marker, index) =>
<Marker
key={index}
position={{lat: marker.currentPositionLat, lng: marker.currentPositionLng}}
onClick={() => this.props.onToggleOpen(index)}
tracksViewChanges={false}
>
{this.props.isOpen && this.props.infoIndex === index &&
<InfoWindow onCloseClick={() => this.props.onToggleOpen(index)}>
<div>
<h6>Truck Id: {marker.vehicleName}</h6>
<b>Registration Plate: {marker.registrationNumber}</b>
<br/>
<p>
Position recorded on <i>{marker.time}</i> <br/>
Engine is [{marker.currentIgnitionState}] <br/>
Fuel Level: {marker.currentFuelLevel} L left <br/>
Speed: {marker.currentSpeed} Km/h <br/>
</p>
</div>
</InfoWindow>}
</Marker>
);
return <div>{listComponent}</div>;
}
};
export default connect(
state => state.mainArea.markersReducer,
dispatch => bindActionCreators(markersActionCreators, dispatch)
)(MarkersList);
Я гарантировал, что displayMarkers имеет правильное значение после выбора чего-либо (в этом случае displayMarkers изменяется с 4000 записей на 1). Я прошелся по всему приложению, чтобы убедиться, что каждое вычисленное мной значение верно, когда происходит такое неудачное поведение. Кроме того, метод рендеринга не вызывается второй раз перед остановкой. Изменение с 4000 отображаемых маркеров на 3999 или 3980 работает должным образом.
Для лучшего обзора приложения я создал CodeSandbox (он ничего не отображает, потому что отсутствует ключ API и данные): https://codesandbox.io/s/v830m9p7ry?fontsize=14&view=editor
Я новичок в реагировании и редукции, и я действительно не знаю, что мне следует проверить или сделать дальше, чтобы выяснить, почему это происходит.
Заранее спасибо за любую помощь!
РЕДАКТИРОВАТЬ: Добавлен анализ производительности . А также
отображается после 30-секундной отметки в анализе производительности .
Он рендерит каждый маркер и удаляет их один за другим.