如何在任何子节点上使用相同的谷歌地图组件实例?



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

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

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

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

任何这方面的帮助将不胜感激。

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

  1. 将同级节点添加到索引.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. 使用回调引用将地图插入任何需要的地方。如何在组件上实际使用它取决于您;我做了一个返回这个函数的钩子。
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道具。我将尽快尝试并更新我的答案。

您可以尝试使用门户来实现它

门户提供了一种将子节点呈现到父组件的 DOM 层次结构之外的 DOM 节点的一流方法。

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

最新更新