2

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

这是场景:

  1. 加载带有地图和 2-3 个标记的页面(好的)
  2. 单击导航栏上的选项卡 -> 页面以单页应用程序方式呈现其他内容(好的)
  3. 单击导航栏上返回地图的选项卡 -> 页面呈现地图但不呈现标记。

我在该州持有标记数据,并将它们应用到onGoogleApiLoaded={({map, maps}) => this.renderMarkers(map, maps)}.

我设法通过renderMarkerssetTimeout一秒钟内换行来解决这个问题,并且它以这种方式加载得很好。

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

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

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

4

2 回答 2

1

在我进一步分解问题后,我明白了这一点。问题是由于我丢失了保持在 Map 组件状态的标记数据(这是具有导航栏的组件的子组件)。

所以流程是这样的:

  1. 页面的首次渲染-> 一切都加载正常,因为所有内容都是第一次渲染(包括标记)。
  2. 我渲染另一个组件,前一个组件被破坏并丢失状态。
  3. 我重新渲染了 Map 组件,但它没有状态,因此它没有可供标记使用的数据。

自然地,解决方案是将状态移动到更高一级的父级并将其作为 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.

于 2018-06-07T20:19:14.273 回答
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}
    />
  );
}
于 2018-06-07T07:03:34.290 回答