我正在构建一个React应用,其中许多标记都显示在react-google-maps地图上。用户可以过滤标记,以便不能一次显示所有标记。使用MarkerClusterer显示4000个标记可以正常工作。显示它们需要花费合理的时间,之后地图才响应。
现在,当我尝试在渲染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个)。我逐步浏览了整个应用程序,以确保在发生这种不幸行为时,我计算出的每个值都是正确的。此外,在冻结之前不会再次调用render方法。从4000个显示的标记更改为3999或3980可以正常工作。
为更好地了解该应用程序,我制作了一个CodeSandbox(由于api键和数据丢失,它无法呈现任何内容):https://codesandbox.io/s/v830m9p7ry?fontsize=14&view=editor
我是新来的反应者和还原者,我真的不知道该怎么做,我应该测试或下一步做什么。
在此先感谢您的帮助!
编辑:Added performance analysis。并且 this is displayed after the 30 second mark in the performance analysis。 它正在渲染每个标记,并正在将它们逐个删除。