【问题标题】:Rendering issue with custom map component inside tabbed form of react-adminreact-admin 的选项卡式表单中自定义地图组件的渲染问题
【发布时间】:2021-10-28 16:43:41
【问题描述】:

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

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

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

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

欢迎任何见解。

非常感谢您抽出宝贵时间。

【问题讨论】:

    标签: reactjs leaflet react-admin react-leaflet


    【解决方案1】:

    这个问题已经在 SO 中讨论了很多。如果您搜索一下,您可以找到原因。你真正需要做的是两件事:

    1. 在切换选项卡时使用setInterval 结合地图的invalidateSize 方法,然后在卸载组件时对其进行清理
    2. 使用 useEffect 更改 mapZoom 和 view,因为它们是不可变的。

    因此,由于您使用 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

    【讨论】:

    • 精彩回顾!如果可能,在地图选项卡显示后使用 invalidateSize,而不是使用 setInterval。
    • 非常感谢更正和更新的沙箱。如果你不介意我问,你提到的在 SO 上讨论过的问题是这个与 Leaflet 相关的特定问题,还是更一般的 ReactJS 问题?
    • 是传单相关的
    猜你喜欢
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多