Reputation: 606
I have a small map application. When a user clicks the search button, I want the map to zoom into a specific area on the map and have a box appear. I am getting an error that there is already a source with this ID. What does this mean and how can I fix it?
const Map = (props) => {
console.log(props);
const mapContainerRef = useRef(null);
const [lng, setLng] = useState(5);
const [lat, setLat] = useState(34);
const [zoom, setZoom] = useState(1.5);
const [globalMap, setMap] = useState(Object());
// Initialize map when component mounts
useEffect(() => {
const map = new mapboxgl.Map({
container: mapContainerRef.current,
style: 'mapbox://styles/mapbox/dark-v10',
center: [lng, lat],
zoom: zoom
});
setMap(map);
// Disable default box zooming.
map.boxZoom.disable();
// Create a popup, but don't add it to the map yet.
var popup = new mapboxgl.Popup({
closeButton: false
});
// Add navigation control (the +/- zoom buttons)
map.addControl(new mapboxgl.NavigationControl(), 'top-right');
map.on('move', () => {
setLng(map.getCenter().lng.toFixed(4));
setLat(map.getCenter().lat.toFixed(4));
setZoom(map.getZoom().toFixed(2));
});
map.on('load', function () {
// function omitted to save space
}
// Clean up on unmount
return () => map.remove();
}, []); // eslint-disable-line react-hooks/exhaustive-deps
React.useEffect(() => {
if(props.show) {
// Coordinates (eventually connect to back end)
var northEast = [131.308594, 46.195042];
var southEast = [117.597656, 8.233237];
var southWest = [79.101563, 32.842674];
var northWest = [86.847656, 44.715514];
var maxSouth = Math.min(southEast[1], southWest[1]);
var maxWest = Math.min(southWest[0], northWest[0]);
var maxNorth = Math.max(northWest[1], northEast[1]);
var maxEast = Math.max(northEast[0], southEast[0]);
globalMap.fitBounds([
[maxWest - 5, maxSouth - 5], // southwestern corner of the bounds
[maxEast + 5, maxNorth + 5] // northeastern corner of the bounds
]);
// Add bounding box to the map
// Defines bounding box
// Polygons seem to be the preferred method according to my research
globalMap.addSource('route', {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'LineString',
'coordinates': [
northEast, southEast, southWest, northWest, northEast
]
}
}
});
// Draws bounding box
globalMap.addLayer({
'id': 'route',
'type': 'line',
'source': 'route',
'layout': {
'line-join': 'round',
'line-cap': 'round'
},
'paint': {
'line-color': '#ff0000',
'line-width': 5
}
});
}
});
The error occurs at the line globalMap.addSource('route', { ...
. It also shows the setLng, setLat, setZoom section.
Upvotes: 0
Views: 1346
Reputation: 47
I solved this 'existing layer id' with adding
return () => {
mapRef.current.remove();
};
before exiting the useEffect() block:
useEffect(() =>{
*your code here*
***add useEffect's return:***
return () => {
mapRef.current.remove();
};
})
return(
***function return here***
(<div ref={mapContainerRef}
className="map-container" />
)
Upvotes: 0
Reputation: 86
I am having the same issue. To my understanding, the source is getting added twice or more to the map because of some re render. You could also check if this source id exists or no before adding it. My temporary solution for now is to use React Mapbox gl components to render a layer.
Upvotes: 1