i tried to simplified my codes to get sooner a solution, I have a Map component and a DrawFToolbar component, I send map as props to DrawFToolbar component, there are some console lines in DrawFToolbar to check.so in console I get this messages: "DrawFToolbar rendered" and "DrawFToolbar useEffect hook triggered" and then map send to console, it seems to be a valid map element () but when compiler reach to run any method of map , i get this error: "map.addLayer is not a function" . for example i want to add a marker to map and get mentioned error. following i put my codes it make easy solving this error :
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 © <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
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;
I expect to know why leaflet map's methods in DrawFToolbar do not work whereas map exist and apparently is a valid leaflet map. thanks
The map
needed for .addTo(map)
is NOT the map container DOM Element (stored here in mapRef
), but the JS object returned by Leaflet L.map()
factory:
const map = L.map(mapRef.current)
// ^-- This object
(The same that you use for map.remove()
)
So in your case you could simply store that object in another React ref, to provide it to your <DrawFToolbar>
Component:
function Map() {
/** ref for the DOM Element */
const mapContainerRef = useRef(null);
/** ref for the Leaflet JS object */
const mapObjectRef = useRef();
useEffect(() => {
if (mapContainerRef.current) {
const map = L.map(mapContainerRef.current);
// Store it in its own ref
mapObjectRef.current = map;
return () => {
map.remove();
};
}
}, []);
return (
<div ref={mapContainerRef}>
<DrawFToolbar mapRef={mapObjectRef} />
</div>
);
}