0

我正在寻找一种在我的应用程序中的任何地方使用相同谷歌地图实例的方法。毕竟每次地图加载都是收费的......

我正在使用google-map-react。在 ComponentDidMount 上创建了一个新的Map实例,所以对我来说,第一个要求是保持该组件安装是有道理的,最有可能靠近组件树的顶部。

最终结果应该是任何想要渲染地图的组件都应该:

  • 如果尚未安装地图组件,请安装它。
  • 以某种方式回收安装地图的 DOM 节点。

对此的任何帮助将不胜感激。

4

2 回答 2

1

您可以尝试使用Portals来实现它

门户提供了一种一流的方式来将子级呈现到存在于父组件的 DOM 层次结构之外的 DOM 节点中。

但是,用户对地图所做的每项更改(缩放、图层等)都将保留,因此每当您在另一部分中渲染地图时,您也可以将地图重置为初始状态。

于 2019-08-09T21:21:38.487 回答
0

门户确实是正确的方向。我想出了以下方法:

  1. 向 index.html 添加兄弟节点:
<!-- Root node of React app -->
<div id="root"></div>

<!-- Keep the map here while not in use -->
<div id="map-bench">
  <!-- Create the portal using this node as container (2nd argument) -->
  <div id="map-container" style="height: 100%; width: 100%"></div>
</div>
  1. 制作一个在门户内渲染地图的组件,然后将其安装在树顶附近的某个位置;关键是要防止地图被卸载。
return createPortal(renderMap(), document.getElementById("map-container"));
  1. 使用回调 ref 在需要的地方插入地图。如何在组件上实际使用它取决于您;我做了一个返回这个函数的钩子。
    const registerMapOutlet = (rootNode: HTMLDivElement | null) => {
      // THE MAP
      const mapNode = document.getElementById("map-container");

      // Bail out if map node is not found
      if (mapNode === null) return;

      // on mount: Attach map
      if (rootNode) {
        rootNode.replaceWith(mapNode);

        console.log("REGISTERED MAP OUTLET");

        // GoogleMapReact won't load/mount until it is first used
        dispatch(mountMapIfNeeded());
      }

      // on unmount: Return map to bench node
      else {
        const mapBenchNode = document.getElementById("map-bench");

        if (mapBenchNode === null) {
          console.warn("Map Bench node was not found");
          return;
        }

        mapBenchNode.appendChild(mapNode);
      }
    }
  1. 最后,在任何组件上使用地图,如下所示:
// You can pass GoogleMapReact props to this hook
const { registerMapOutlet } = useMapOutlet({});

return <div ref={registerMapOutlet}></div>

google-map-react 1.1.5 版引入了一个shouldUnregisterMapOnUnmount 属性。我会尽快尝试并更新我的答案。

于 2019-11-11T16:33:37.713 回答