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

Next.js项目中React Leaflet Marker图标不显示问题求助

Next.js中React Leaflet Marker图标不显示问题解决

我在Next.js项目中使用React Leaflet组件,发现Marker图标无法正常显示(如图所示),自定义Marker也不生效。搭建了一个简单的React/Leaflet示例,但Marker完全不显示。

import { useState, useEffect, useRef } from "react";
import "leaflet/dist/leaflet.css";
import {
  MapContainer,
  TileLayer,
  Marker,
  Popup,
  useMap,
  useMapEvents,
} from "react-leaflet";
import { useSelector } from "react-redux";
import { useCallback } from "react";
import { useMemo } from "react";


function LocationMarker({ lat, lng }) {
  const [position, setPosition] = useState(null);
  const [bbox, setBbox] = useState([]);
  const map = useMap();

  useEffect(() => {
    map.flyTo([lat, lng], map.getZoom());
  }, [lat]);

  return position === null ? null : (
    <Marker position={position}>
      <Popup>You are here</Popup>
    </Marker>
  );
}

export default function EditAddedMap({ lat, lng, setLat, setLng }) {
  const { resturant } = useSelector((state) => state);

  return (
    <MapContainer center={[lat, lng]} zoom={13} scrollWheelZoom={false}>
      <TileLayer
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      <LocationMarker lat={lat} lng={lng} />
      <DraggableMarker lat={lat} lng={lng} setLng={setLng} setLat={setLat} />
    </MapContainer>
  );
}

Marker图标异常

问题排查及解决办法

1. 修复Leaflet默认图标路径

Next.js的静态资源规则导致Leaflet默认marker图标找不到,需手动配置:

  • 从node_modules/leaflet/dist/images文件夹中复制marker-icon.png、marker-icon-2x.png、marker-shadow.png到项目的public/images目录下
  • 在地图组件文件顶部添加以下代码重置图标路径:
import L from 'leaflet';

delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
  iconRetinaUrl: '/images/marker-icon-2x.png',
  iconUrl: '/images/marker-icon.png',
  shadowUrl: '/images/marker-shadow.png',
});

2. 确保地图组件在客户端渲染

Next.js服务端渲染环境不支持Leaflet的DOM操作,需禁用组件SSR:

  • 使用Next.js的dynamic导入地图组件:
// 在使用EditAddedMap的文件中
import dynamic from 'next/dynamic';

const EditAddedMap = dynamic(() => import('./path-to-your-EditAddedMap-file'), {
  ssr: false,
  loading: () => <div>加载地图中...</div>
});

3. 修正LocationMarker组件逻辑

你的LocationMarker中position初始为null且未赋值,导致Marker不渲染,修改如下:

function LocationMarker({ lat, lng }) {
  const [position, setPosition] = useState([lat, lng]);
  const map = useMap();

  useEffect(() => {
    map.flyTo([lat, lng], map.getZoom());
    setPosition([lat, lng]);
  }, [lat, lng, map]);

  return (
    <Marker position={position}>
      <Popup>You are here</Popup>
    </Marker>
  );
}

4. 自定义Marker不生效的处理

自定义图标需确保路径正确且在客户端加载,示例:

import L from 'leaflet';

const customMarker = L.icon({
  iconUrl: '/images/your-custom-marker.png',
  iconSize: [40, 40],
  iconAnchor: [20, 40], // 图标锚点位置
  popupAnchor: [0, -40] // 弹窗相对于图标的位置
});

// 在Marker组件中使用
<Marker position={[lat, lng]} icon={customMarker}>
  <Popup>自定义Marker</Popup>
</Marker>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:15:37