I have a React app that displays a map with some markers on it. The map markers are refreshed by clicking a button that fetches new locations from the Google Maps API. I want to remove the previous location markers from the map on each refresh.
import React, { useEffect, useState } from 'react';
function Map(props) {
const [markers, setMarkers] = useState();
function clearMarkers() {
for(let i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
}
useEffect(() => {
clearMarkers();
if(props.locations.length) {
const googleMarkers = [];
for(let i = 0; i < props.locations.length; i++) {
const marker = new window.google.maps.Marker({...});
googleMarkers.push(marker);
}
setMarkers(googleMarkers);
}
}, [props.locations, props.map]);
}
I have it working, but I am getting a warning from React.
React Hook useEffect has a missing dependency: 'clearMarkers'. Either include it or remove the dependency array
I need the dependency array, so the markers only refresh when there are new props.locations
, but when I include it in the dependency array, I get an infinite loop.
How can I clear the markers off the map before adding new ones without React throwing a warning ? Or should I not be concerned with the warning?
You could consider to store markers via mutable ref object ( as described here ):
const prevMarkersRef = useRef([]);
to distinguish previous markers. And then clear previous markers once locations
prop gets updated:
useEffect(() => {
//clear prev markers
clearMarkers(prevMarkersRef.current);
//render markers
for (let loc of props.locations) {
const marker = createMarker({ lat: loc.lat, lng: loc.lng }, map);
prevMarkersRef.current.push(marker);
}
});
where
function createMarker(position, map) {
return new window.google.maps.Marker({
position: position,
map: map
});
}
function clearMarkers(markers) {
for (let m of markers) {
m.setMap(null);
}
}
Here is a demo
You can try and memoize your clearMarkers function and add it to the dependency array of useEffect using useCallback
As your code reads you are creating a new function on each render so the effect is triggered every time if you add the function to the dependency array
this should work
const cb = useCallback(function clearMarkers() {
for(let i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
}, [markers.length]);
useEffect(() => {
cb();
if (props.locations.length) {
const googleMarkers = [];
for (let i = 0; i < props.locations.length; i++) {
const marker = `marker #${i}`;
googleMarkers.push(marker);
}
setMarkers(googleMarkers);
}
}, [props.locations, cb]);
but you can also just add the clearing loop inside useEffect
and add the markers.length
to the dependency array
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.