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

ReactJS中Leaflet地图无法显示的问题求助

Leaflet地图无法显示问题排查与解决

问题详情

已引入Leaflet的CSS和JS CDN链接,为承载Map组件的#leaflet-map容器设置了宽高,但地图容器仅占用空间却无任何内容显示,控制台无报错信息。

Contact组件代码

import React,{useState, useRef, useEffect} from 'react';
import {BsExclamationLg, BsPatchCheckFill} from "react-icons/bs";
import Map from './Map';
import Blast from "./Blast"

const Contact = () => {

  const[letterClass, setLetterClass] = useState("text-animate");
  useEffect(()=>{
    setTimeout(()=>{
      setLetterClass("text-animate-hover")
    }, 3000)
  },[])

  const [validInput, setValidInput] =useState({
    name:"",
    email:"",
    subject:"",
    message:"",
  })

  const TextAreaRef = useRef(null);
  const form = useRef(null);

  const onSubmit =(e)=>{
    console.log(e);
  }

  const handleChange = (e) => {
    const { name, value } = e.target
    setValidInput((preValue) => {
      return { ...preValue, [name]: value }
    })
  }

  return (
    <>
      <section className='contact-section'>
        <form ref={form} className='contact-form' onSubmit={onSubmit}>
          <div>
            <h2 className='contact__heading'>
              <Blast letterClass={letterClass} arrayStr={["C", "o","n","t", "a", "c", "t", " ", "m", "e"]} indexLetter={12} />
            </h2>  
            <p>Got a question or proposal, or just want to say hello? Go ahead</p>
          </div>  
          <div className='input-wrapper'>
            <div className="form-input-group">
              <input type="text" name="name" placeholder="Name" value={validInput.name} autoComplete='false' onChange={handleChange}/>
              <span className='switch__bg'></span>
            </div>
            <div className="form-input-group">
              <input type="text" name="email" placeholder="Email" value={validInput.email} autoComplete='false' onChange={handleChange}/>
              <span className='switch__bg'></span>
              <BsExclamationLg className='exclamation'/>
              <BsPatchCheckFill className='checkCircle'/>
            </div>
          </div>
          <div className="form-input-group">
              <input type="text" name="subject" placeholder="Subject" value={validInput.subject} autoComplete='false' onChange={handleChange}/>
              <span className='switch__bg'></span>
              <BsExclamationLg className='exclamation'/>
              <BsPatchCheckFill className='checkCircle'/>
            </div>
            <div className="form-input-group">
              <textarea autoComplete='false' ref={TextAreaRef} type="text" placeholder='Message' name="message" value={validInput.message} onChange={handleChange}></textarea>
              <span className='switch__bg'></span>
              <BsExclamationLg className='exclamation'/>
              <BsPatchCheckFill className='checkCircle'/>
            </div>
            <button className='contact-button submit-button' type='submit'>
              <div>
                <span className="text">Shoot</span>
              </div>
            </button>
        </form>  
        <div id="leaflet-map">
          <Map />
        </div>
      </section> 
    </>
  )
}

export default Contact

Map组件代码

import React from 'react';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';

const Map = () => {
    return (
        <div>
            <MapContainer center={[18.494102, 73.932754]} zoom={13} scrollWheelZoom={false}>
                <TileLayer
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
                <Marker position={[18.494102, 73.932754]}>
                    <Popup>Tadaa! Here's where I live</Popup>
                </Marker>
                <div className="map-content">
                    <span>Aaryan Pinto,</span>
                    <br />
                    <span>Location: Pune, India</span>
                    <br />
                    <span>Email: imaryan32@gmail.com</span>
                </div>
            </MapContainer>
        </div>
    )
}

export default Map

排查与解决步骤

1. 给MapContainer设置明确宽高

react-leaflet的MapContainer组件需要自身有明确的尺寸,仅给外层#leaflet-map设置宽高是不够的。可以直接在组件上添加样式:

<MapContainer 
  center={[18.494102, 73.932754]} 
  zoom={13} 
  scrollWheelZoom={false}
  style={{ width: "100%", height: "400px" }} // 新增宽高样式
>

或者通过CSS全局设置:

.leaflet-container {
  width: 100%;
  height: 400px;
}

2. 移除MapContainer内的自定义DOM元素

MapContainer的子元素必须是react-leaflet提供的Leaflet组件(如TileLayer、Marker),不能直接插入自定义div。把你的map-content移到MapContainer外部:

const Map = () => {
    return (
        <div>
            <MapContainer 
                center={[18.494102, 73.932754]} 
                zoom={13} 
                scrollWheelZoom={false}
                style={{ width: "100%", height: "400px" }}
            >
                <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
                <Marker position={[18.494102, 73.932754]}>
                    <Popup>Tadaa! Here's where I live</Popup>
                </Marker>
            </MapContainer>
            {/* 自定义内容移至此处 */}
            <div className="map-content">
                <span>Aaryan Pinto,</span>
                <br />
                <span>Location: Pune, India</span>
                <br />
                <span>Email: imaryan32@gmail.com</span>
            </div>
        </div>
    )
}

3. 验证CDN版本兼容性

确保react-leaflet与Leaflet的版本匹配:

  • react-leaflet v4 对应 Leaflet v1.9.x
  • react-leaflet v3 对应 Leaflet v1.7.x
    同时确保CSS在JS之前引入,加载顺序错误也可能导致地图无法渲染。

4. 确保组件挂载时机正确(可选)

如果组件是动态挂载(如路由切换场景),可通过状态控制MapContainer的渲染时机,确保DOM已准备好:

import React, { useEffect, useState } from 'react';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';

const Map = () => {
    const [isReady, setIsReady] = useState(false);

    useEffect(() => {
        setIsReady(true);
    }, []);

    if (!isReady) return null;

    return (
        <div>
            <MapContainer 
                center={[18.494102, 73.932754]} 
                zoom={13} 
                scrollWheelZoom={false}
                style={{ width: "100%", height: "400px" }}
            >
                <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
                <Marker position={[18.494102, 73.932754]}>
                    <Popup>Tadaa! Here's where I live</Popup>
                </Marker>
            </MapContainer>
            <div className="map-content">
                <span>Aaryan Pinto,</span>
                <br />
                <span>Location: Pune, India</span>
                <br />
                <span>Email: imaryan32@gmail.com</span>
            </div>
        </div>
    )
}

export default Map

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:40:07