You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Leaflet地图移动端渲染异常:登录跳转后导航栏不可见

问题:React中Leaflet地图移动端渲染异常

我创建了用于复现问题的仓库,在React.js中使用Leaflet时遇到以下问题:

  • 移动端视图下Leaflet地图发生溢出,且导航栏不可见
  • 该问题仅在用户登录后从登录页跳转至带地图的路由时出现,刷新浏览器后导航栏即可正常显示

Map.tsx

import type {
  Layer,
  LayerGroup,
  FitBoundsOptions,
  LatLngBoundsExpression,
  MapOptions,
} from "leaflet";
import { Control, Map as LeafletMap, tileLayer, control, Util } from "leaflet";
import "leaflet/dist/leaflet.css";
import type { HTMLProps } from "react";
import { useCallback, useEffect, useState } from "react";
import { useResizeObserverRef } from "rooks";

import "./Map.css";

export type ControlledLayer = {
  addLayer(layer: Layer): void;
  removeLayer(layer: Layer): void;
};

export type LeafletContextInterface = Readonly<{
  __version: number;
  map: LeafletMap;
  layerContainer?: ControlledLayer | LayerGroup;
  layersControl?: Control.Layers;
  overlayContainer?: Layer;
  pane?: string;
}>;

const CONTEXT_VERSION = 1;

function createLeafletContext(map: LeafletMap): LeafletContextInterface {
  return Object.freeze({ __version: CONTEXT_VERSION, map });
}

type DivProps = HTMLProps<HTMLDivElement>;

export interface MapContainerProps extends MapOptions, DivProps {
  bounds?: LatLngBoundsExpression;
  boundsOptions?: FitBoundsOptions;
  whenReady?: () => void;
  isDrawActive?: boolean;
  isGeoSearchActive?: boolean;
  onGetMapBounds?: () => void;
  containerClassName?: string;
}

export function Map({
  center = [0, 0],
  zoom = 1,
  bounds,
  boundsOptions = { padding: [500, 500], maxZoom: 21 },
  whenReady,
  containerClassName,
  className,
  ...options
}: MapContainerProps) {
  const [context, setContext] = useState<LeafletContextInterface | null>(null);

  const handleResizeMapContainer = Util.throttle(
    () => {
      console.log("invalidate size");
      context?.map.invalidateSize();
    },
    500,
    undefined
  );

  const [mapContainerRef] = useResizeObserverRef(handleResizeMapContainer);

  const mapRef = useCallback((node: HTMLDivElement | null) => {
    if (node !== null && context === null) {
      const openStreetMap = tileLayer(
        "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        {
          attribution:
            '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
        }
      );
      const map = new LeafletMap(node, {
        zoomControl: false,
        layers: [openStreetMap],
        ...options,
      });

      const baseMaps = {
        OpenStreetMap: openStreetMap,
      };
      control.layers(baseMaps).addTo(map);

      if (center != null && zoom != null) {
        map.setView(center, zoom);
      } else if (bounds != null) {
        map.fitBounds(bounds, boundsOptions);
      }
      if (whenReady != null) {
        map.whenReady(whenReady);
      }

      control.zoom({ position: "bottomright" }).addTo(map);

      setContext(createLeafletContext(map));
    }
  }, []);

  useEffect(() => {
    return () => {
      context?.map.remove();
    };
  }, []);

  return (
    <div className={containerClassName} ref={mapContainerRef}>
      <div
        ref={mapRef}
        className={className ? className : `flex h-full w-full flex-1`}
      />
    </div>
  );
}

补充信息:

  • 已部署项目可直观查看该问题
  • 录制了问题发生过程的视频
  • 编辑补充:创建了使用React Leaflet的分支,该分支部署后同样存在此问题

内容的提问来源于stack exchange,提问作者Matt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 00:27:08