使用 React 状态,如何在添加新标记之前从 Google 地图中删除标记?
Using React state, how can I remove markers from a Google map before adding new ones?
我有一个 React 应用程序,可以显示带有一些标记的地图。通过单击从 Google 地图 API 中获取新位置的按钮来刷新地图标记。我想在每次刷新时从地图中删除以前的位置标记。
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]);
}
我可以正常工作,但收到来自 React 的警告。
React Hook useEffect has a missing dependency: 'clearMarkers'. Either include it or remove the dependency array
我需要依赖数组,所以标记只有在有新的时候才会刷新props.locations
,但是当我把它包含在依赖数组中时,我得到了一个无限循环。
如何在添加新标记之前清除地图上的标记而 React 不会抛出警告?还是我不应该关心这个警告?
您可以尝试记忆您的 clearMarkers 函数,并使用 useCallback
将其添加到 useEffect 的依赖数组中
当您读取代码时,您将在每个渲染器上创建一个新函数,因此如果将该函数添加到依赖项数组,每次都会触发效果
这应该有效
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]);
但您也可以只在 useEffect
内添加清除循环并将 markers.length
添加到依赖数组
您可以考虑通过可变引用对象(as described here)存储标记:
const prevMarkersRef = useRef([]);
区分前个标记。然后在 locations
属性更新后清除之前的标记:
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);
}
});
哪里
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);
}
}
这是一个demo
我有一个 React 应用程序,可以显示带有一些标记的地图。通过单击从 Google 地图 API 中获取新位置的按钮来刷新地图标记。我想在每次刷新时从地图中删除以前的位置标记。
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]);
}
我可以正常工作,但收到来自 React 的警告。
React Hook useEffect has a missing dependency: 'clearMarkers'. Either include it or remove the dependency array
我需要依赖数组,所以标记只有在有新的时候才会刷新props.locations
,但是当我把它包含在依赖数组中时,我得到了一个无限循环。
如何在添加新标记之前清除地图上的标记而 React 不会抛出警告?还是我不应该关心这个警告?
您可以尝试记忆您的 clearMarkers 函数,并使用 useCallback
当您读取代码时,您将在每个渲染器上创建一个新函数,因此如果将该函数添加到依赖项数组,每次都会触发效果
这应该有效
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]);
但您也可以只在 useEffect
内添加清除循环并将 markers.length
添加到依赖数组
您可以考虑通过可变引用对象(as described here)存储标记:
const prevMarkersRef = useRef([]);
区分前个标记。然后在 locations
属性更新后清除之前的标记:
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);
}
});
哪里
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);
}
}
这是一个demo