反应谷歌地图标记在组件重新渲染后消失

时间:2018-06-07 06:26:09

标签: javascript reactjs react-router-dom react-google-maps

我遇到了react-google-maps模块的问题,即标记和组件重新渲染。

这是情景:

  1. 加载带有地图和2-3个标记的页面(确定)
  2. 点击导航栏上的标签 - >页面以单页面应用程序方式呈现其他内容(ok)
  3. 点击导航栏上返回地图的标签 - >页面渲染地图但不渲染标记。
  4. 我在州内持有标记数据,我将它们应用于onGoogleApiLoaded={({map, maps}) => this.renderMarkers(map, maps)}中的地图。

    我设法通过将renderMarkers包裹在setTimeout的一秒钟来解决这个问题,并以这种方式加载。

    我不喜欢这个解决方案,我相信我根本就不应该这样做。我相信这些标记试图将自己置于未渲染的地图上,但很奇怪即使没有setTimeout它也适用于默认页面(可能与反应组件生命周期有关,我不知道)。 / p>

    地图完全加载后,有没有办法附加属性onGoogleApiLoaded={({map, maps}) => this.renderMarkers(map, maps)}?或者至少延迟它,直到我100%确定地图已加载而不是一些随机秒数。

    编辑:我正在使用marker.setMap(map)方法分配标记,我只是尝试在标记的构造函数中设置属性map: map,但行为保持不变。

2 个答案:

答案 0 :(得分:1)

在我解决了这个问题后,我想到了这一点。问题是由于我丢失了保存在Map组件状态的标记数据(这是具有导航栏的组件的子组件)。

所以流程是这样的:

  1. 首页渲染 - >一切都很好,因为所有东西都是第一次渲染(包括标记)。
  2. 我渲染另一个组件,前一个组件被销毁并失去状态。
  3. 我重新渲染了Map组件,但它没有状态,因此它没有可供标记使用的数据。
  4. 当然,解决方案是将状态向上移动一级到父级并将其作为Map组件的支柱传递下来,现在一切都按原样运行。

    <强>奖金:

    我想提一下我必须解决的另一件事,但对于遇到这个问题的其他人来说不一定有用: 我使用导航栏来浏览我的页面(使用react-router-dom)。

    当将状态更高级别移动到父级时,参数将不会像<Route那样传递给<Route path="/" component={Map} markerData={this.state.markerData}/>元素,而是使用render属性,如下所示: <Route exact path="/" render={props => <Map markerData={this.state.markerData}/>}以便Map组件获取道具,而不是Router

答案 1 :(得分:0)

当您说单击选项卡并且页面呈现其他内容时,您可能正在卸载地图组件。如果您将状态标记保存在状态中,则可以在componentWillUnmount中自行检查。

componentWillUnmount() {
  console.log('Unmount');
}

如果您的控制台中显示该控制台日志,则表示您正在卸载组件并丢失您所在州的标记数据。

现在,为了使用您的标记加载地图,您可以等待地图使用componentDidMount完全加载。我不确定react-google-maps与react-leaflet(我遇到过的地图组件)有什么不同,但我猜测地图有一个属性,你可以将它保存在状态中。您应该使用componentWillMountcomponentDidUnmount生命周期方法来获取标记数据,而不是超时。

componentDidMount() { // It should work with componentWillMount too
  this.fetchMarkersData();
}

fetchMarkersData() {
  // ... get your data
  this.setState({ markers: markersData });
}

render() {
  return (
    <MapComponent
      markers={this.state.markers}
    />
  );
}