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

向DrawFToolbar传递Map作为Props后调用方法报错问题排查

为什么Leaflet Map的方法在子组件中无法调用?

你遇到的问题是:将Map组件中的map以props传入DrawFToolbar后,控制台能打印出map对象,但调用map.addLayer(或addTo(map))时会报错map.addLayer is not a function,尽管看起来map是有效的实例。

问题代码

Map组件

import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import 'leaflet-draw/dist/leaflet.draw.css';
import 'leaflet-toolbar/dist/leaflet.toolbar.css';
import 'leaflet-draw/dist/leaflet.draw.js';
import 'leaflet-toolbar/dist/leaflet.toolbar.js';
import React, { useState, useEffect, useRef } from 'react';
import Axios from "axios";
import DrawFToolbar from './DrawFToolbar';
import 'leaflet-toolbar';

function Map() {
  const mapRef = useRef(null);  
  const [drawToolbarLoaded, setDrawToolbarLoaded] = useState(false);

  useEffect(() => {
    if (mapRef.current) {
      const map = L.map(mapRef.current).setView([51.505, -0.09], 13);

      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
        maxZoom: 18,
      }).addTo(map);

      setDrawToolbarLoaded(true);
    
      return () => {
        map.remove();
      }
    }
  }, []);

  return (
    <div ref={mapRef} style={{ height: '400px' }} > 
      {drawToolbarLoaded && <DrawFToolbar mapRef={mapRef} />}
    </div>
  );
}

export default Map

DrawFToolbar组件

import { useEffect } from 'react';
import L from 'leaflet';
import 'leaflet-draw/dist/leaflet.draw.css';
import 'leaflet-toolbar/dist/leaflet.toolbar.css';
import 'leaflet-draw/dist/leaflet.draw.js';
import 'leaflet-toolbar/dist/leaflet.toolbar.js';
import 'leaflet/dist/leaflet.css';

function DrawFToolbar(props) {
  console.log('DrawFToolbar rendered');
  useEffect(() => {
    console.log('DrawFToolbar useEffect hook triggered');
    const map = props.mapRef.current;
    
    console.log(map);
    if (map) {
      L.marker([51.6, -0.09]).addTo(map);
    }
  }, [props.mapRef]);

  return null;
}

export default DrawFToolbar;

问题根源

你传递给DrawFToolbar的mapRef.current是DOM元素(即承载地图的div),而不是Leaflet创建的map实例。Leaflet的addTo()方法需要接收的是Leaflet Map对象,而不是DOM节点,所以才会报错map.addLayer is not a function。

解决方案

在Map组件中单独存储Leaflet的map实例,然后将这个实例传递给子组件:

  • 在Map组件中新增一个ref用于存储Leaflet map实例
  • 将该实例作为props传给DrawFToolbar,而不是DOM元素的ref

修改后的Map组件

import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import 'leaflet-draw/dist/leaflet.draw.css';
import 'leaflet-toolbar/dist/leaflet.toolbar.css';
import 'leaflet-draw/dist/leaflet.draw.js';
import 'leaflet-toolbar/dist/leaflet.toolbar.js';
import React, { useState, useEffect, useRef } from 'react';
import Axios from "axios";
import DrawFToolbar from './DrawFToolbar';
import 'leaflet-toolbar';

function Map() {
  const mapRef = useRef(null);
  // 新增ref存储Leaflet map实例
  const mapInstanceRef = useRef(null);  
  const [drawToolbarLoaded, setDrawToolbarLoaded] = useState(false);

  useEffect(() => {
    if (mapRef.current) {
      const map = L.map(mapRef.current).setView([51.505, -0.09], 13);
      // 将map实例存入ref
      mapInstanceRef.current = map;

      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
        maxZoom: 18,
      }).addTo(map);

      setDrawToolbarLoaded(true);
    
      return () => {
        map.remove();
        // 清空实例ref
        mapInstanceRef.current = null;
      }
    }
  }, []);

  return (
    <div ref={mapRef} style={{ height: '400px' }} > 
      {/* 传递map实例给子组件 */}
      {drawToolbarLoaded && <DrawFToolbar map={mapInstanceRef.current} />}
    </div>
  );
}

export default Map

修改后的DrawFToolbar组件

import { useEffect } from 'react';
import L from 'leaflet';
import 'leaflet-draw/dist/leaflet.draw.css';
import 'leaflet-toolbar/dist/leaflet.toolbar.css';
import 'leaflet-draw/dist/leaflet.draw.js';
import 'leaflet-toolbar/dist/leaflet.toolbar.js';
import 'leaflet/dist/leaflet.css';

function DrawFToolbar(props) {
  console.log('DrawFToolbar rendered');
  useEffect(() => {
    console.log('DrawFToolbar useEffect hook triggered');
    const map = props.map;
    
    console.log(map);
    if (map) {
      L.marker([51.6, -0.09]).addTo(map);
    }
  }, [props.map]);

  return null;
}

export default DrawFToolbar;

这样修改后,子组件接收的是真正的Leaflet Map实例,调用addTo(map)或其他Map方法就不会报错了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:55:58