如何在任何 child 上使用相同的 google 地图组件实例?
How to use the same google map component instance on any child?
我正在寻找一种在我的应用程序中的任何位置使用相同 google 地图实例的方法。毕竟每个地图加载都是收费的...
我正在使用 google-map-react. A new Map 实例是在 ComponentDidMount 上创建的,所以对我来说,第一个要求是保持该组件已安装,很可能靠近组件树的顶部。
最终结果应该是任何想要渲染地图的组件都应该:
- 如果地图组件还没有挂载,请挂载它。
- 以某种方式回收安装地图的 DOM 节点。
如有任何帮助,我们将不胜感激。
您可以尝试使用 Portals
来实现
Portals 提供了第一种class 方法来将子项渲染到 DOM 节点中,该节点存在于父组件的 DOM 层次结构之外。
但是,用户对地图所做的每项更改(缩放、图层等)都将保留,因此当您在另一个部分渲染地图时,您也可以将地图重置为初始状态。
门户确实是正确的方向。我想出了以下方法:
- 添加兄弟节点到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>
- 制作一个在门户内呈现地图的组件,然后将其安装在树顶部附近的某个位置;重点是防止地图卸载。
return createPortal(renderMap(), document.getElementById("map-container"));
- 使用回调引用将地图插入到您需要的任何地方。如何在您的组件上实际使用它取决于您;我做了一个钩子returns这个函数。
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);
}
}
- 最后,像这样在任何组件上使用地图:
// You can pass GoogleMapReact props to this hook
const { registerMapOutlet } = useMapOutlet({});
return <div ref={registerMapOutlet}></div>
google-map-react 的 1.1.5 版本引入了一个 shouldUnregisterMapOnUnmount 道具。我会尽快试验并更新我的答案。
我正在寻找一种在我的应用程序中的任何位置使用相同 google 地图实例的方法。毕竟每个地图加载都是收费的...
我正在使用 google-map-react. A new Map 实例是在 ComponentDidMount 上创建的,所以对我来说,第一个要求是保持该组件已安装,很可能靠近组件树的顶部。
最终结果应该是任何想要渲染地图的组件都应该:
- 如果地图组件还没有挂载,请挂载它。
- 以某种方式回收安装地图的 DOM 节点。
如有任何帮助,我们将不胜感激。
您可以尝试使用 Portals
来实现Portals 提供了第一种class 方法来将子项渲染到 DOM 节点中,该节点存在于父组件的 DOM 层次结构之外。
但是,用户对地图所做的每项更改(缩放、图层等)都将保留,因此当您在另一个部分渲染地图时,您也可以将地图重置为初始状态。
门户确实是正确的方向。我想出了以下方法:
- 添加兄弟节点到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>
- 制作一个在门户内呈现地图的组件,然后将其安装在树顶部附近的某个位置;重点是防止地图卸载。
return createPortal(renderMap(), document.getElementById("map-container"));
- 使用回调引用将地图插入到您需要的任何地方。如何在您的组件上实际使用它取决于您;我做了一个钩子returns这个函数。
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);
}
}
- 最后,像这样在任何组件上使用地图:
// You can pass GoogleMapReact props to this hook
const { registerMapOutlet } = useMapOutlet({});
return <div ref={registerMapOutlet}></div>
google-map-react 的 1.1.5 版本引入了一个 shouldUnregisterMapOnUnmount 道具。我会尽快试验并更新我的答案。