在 react-admin 的选项卡形式内使用自定义地图组件呈现问题

Rendering issue with custom map component inside tabbed form of react-admin

我在一个项目中使用 React-admin 来获取一些资源,我使用选项卡式表单来更好地组织字段和输入。我基于 react-leaflet 创建了一个相当简单的自定义地图组件,我在这些选项卡式表单中使用了它。

我遇到了一个奇怪的问题,即当地图位于第一个选项卡以外的其他选项卡上时,其内容无法正确显示。似乎地图“认为”视口比实际小得多。重新加载页面(甚至只是在 Chrome 中打开开发人员工具)会强制重新呈现页面并导致地图开始正常运行。

为了更好地演示,我创建了这个简单的 Codesandbox project。它有来自 RA 教程的用户资源,带有两个选项卡。两者都包含地图组件的一个实例,但第一个选项卡上的地图可以立即正常工作,而第二个选项卡上的地图则呈现不正确。

我承认我在这些事情上仍然有点菜鸟,所以我很可能做错了什么,但我已经为此挠头好几个小时了,我想开始消除可能的罪魁祸首。

欢迎任何见解。

非常感谢您的宝贵时间。

这个问题已经在SO中讨论了很多。如果您稍微搜索一下,就会找到原因。您实际需要做的是两件事:

  1. 在切换选项卡时将setInterval与地图的invalidateSize方法结合使用,然后在组件卸载时将其清除
  2. 使用 useEffect 更改地图缩放和视图,因为它们是不可变的。

因此,由于您使用的是 react-leaflet 版本 2。7.x 您需要使用 ref:

获取地图实例
const mapRef = useRef();

useEffect(() => {
    if (!mapRef.current) return;

    const map = mapRef.current.leafletElement;
    const mapZoom = zoom || defaultZoom;

    let intervalInstance;

    if (!center && marker) {
      map.setView(marker, mapZoom);
      intervalInstance = setInterval(() => map.invalidateSize(), 100);
    } else if (!center) {
      map.setView([0.0, 0.0], mapZoom);
    }
    map.setZoom(mapZoom);

    return () => clearInterval(intervalInstance);
  }, []);

<LeafletMap
   ref={mapRef}
   center={marker}
   zoom={defaultZoom}
   className={classes.leafletContainer}
>

Demo