【问题标题】:React google maps Markers disappear after component re-render组件重新渲染后反应谷歌地图标记消失
【发布时间】:2018-11-16 22:58:44
【问题描述】:

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

这是场景:

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

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

我设法通过将renderMarkers 包装在一秒钟的setTimeout 中解决了这个问题,并且它以这种方式加载良好。

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    现在,要使用标记加载地图,您可以等待地图完全加载 componentDidMount。我不确定 react-google-maps 与 react-leaflet (我有经验的地图组件)有何不同,但我猜地图有一个属性,你可以在其中传递你保持在状态中的标记。您可能应该使用 componentWillMountcomponentDidUnmount react 生命周期方法来获取标记数据,而不是超时。

    componentDidMount() { // It should work with componentWillMount too
      this.fetchMarkersData();
    }
    
    fetchMarkersData() {
      // ... get your data
      this.setState({ markers: markersData });
    }
    
    render() {
      return (
        <MapComponent
          markers={this.state.markers}
        />
      );
    }
    

    【讨论】:

    • 是的,我的地图组件卸载,这是预期的行为。我已经按照你说的做了。问题在于将标记添加到地图时,而不是在实例化标记时。我开始相信我应该尝试使用标记的属性 map: map, 添加它们。
    【解决方案2】:

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

    所以流程是这样的:

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

    当然,解决方案是将 state 上移一级到父级,并将其作为 Map 组件的 prop 向下传递,现在一切正常。

    奖励:

    我想提一下我必须解决的另一件事,但对于偶然发现此问题的其他人不一定有用: 我正在使用导航栏来浏览我的页面(使用react-router-dom)。

    当将状态移动到更高级别的父级时,参数不会像这样传递给&lt;Route元素:&lt;Route path="/" component={Map} markerData={this.state.markerData}/&gt;,而是使用像这样的render属性:&lt;Route exact path="/" render={props =&gt; &lt;Map markerData={this.state.markerData}/&gt;},这样Map 组件获取道具而不是 Router

    【讨论】:

      猜你喜欢
      • 2021-12-20
      • 2012-12-19
      • 2020-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 2013-11-18
      相关资源
      最近更新 更多