使用react-google-maps/api时如何正确处理路由变化?
How to correctly handle route changes when using react-google-maps/api?
我有一个具有以下结构的 react-router-dom
路由器:
...
...
<BrowserRouter>
...
<Switch>
<Route exact path="/" component={Landing} />
<Route path="/about" component={About} />
<Route path="/dashboard" component={MyAccount} />
<Route path="/register" component={Register} />
<Route path="/login" component={Login} />
</Switch>
</Router>
....
我的 Landing
组件使用 @react-google-maps/api
库有条件地显示 MapContainer
组件:
import { GoogleMap, LoadScript, Marker, InfoWindow } from '@react-google-maps/api';
const containerStyle = {
width: '100%',
height: '400px'
};
const MapComponent = ({ trips }) => {
const [map, setMap] = useState(null);
const [ selected, setSelected ] = useState({});
const [ currentPosition, setCurrentPosition ] = useState({});
const success = position => {
const currentPosition = {
lat: position.coords.latitude,
lng: position.coords.longitude
}
setCurrentPosition(currentPosition);
};
const onSelect = item => {
setSelected(item);
};
const onLoad = useCallback(function callback(map) {
const bounds = new window.google.maps.LatLngBounds();
map.fitBounds(bounds);
setMap(map)
}, []);
const onUnmount = useCallback(function callback(map) {
setMap(null)
}, []);
const getPosition = () => {
return new Promise((res, rej) => {
navigator.geolocation.getCurrentPosition(res, rej);
});
}
const setPositionFromGeolocation = async () => {
const res = await getPosition();
const currentPosition = {
lat: res.coords.latitude,
lng: res.coords.longitude
}
setCurrentPosition(currentPosition);
}
useEffect(() => {
setPositionFromGeolocation();
},[setPositionFromGeolocation]);
return (
<LoadScript
googleMapsApiKey={process.env.REACT_APP_GOOGLE_MAPS_API_KEY}
>
<GoogleMap
mapContainerStyle={containerStyle}
center={currentPosition}
zoom={2}
onLoad={onLoad}
onUnmount={onUnmount}
>
{Array.from(trips).map(trip => {
const position = {
lng: trip.geometry.coordinates[0],
lat: trip.geometry.coordinates[1]
}
return (
<Marker
key={trip._id}
position={position}
onClick={() => onSelect(trip)}
/>
)
})
}
{
selected.geometry && (
<InfoWindow
position={{
lng: selected.geometry.coordinates[0],
lat: selected.geometry.coordinates[1]
}}
clickable={true}
onCloseClick={() => setSelected({})}
>
<p>{selected.description}</p>
</InfoWindow>
)
}
</GoogleMap>
</LoadScript>
);
}
当我改变路线时,我得到这些 errors in console。我相信,这些错误的发生是因为我使用 navigator.geolocation.getCurrentPosition
通过 async/await
语法获取当前用户位置。除了我忘记添加的try/catch,有人可以指出我遗漏了什么或做错了什么吗?
原来,我忘记将 trips
prop 添加到 useEffect
作为依赖项,它正在从 Landing
组件传递到 MapComponent
组件。所以 useEffect
的最终版本应该是这样的:
useEffect(() => {
setPositionFromGeolocation();
},[trips]);
我有一个具有以下结构的 react-router-dom
路由器:
...
...
<BrowserRouter>
...
<Switch>
<Route exact path="/" component={Landing} />
<Route path="/about" component={About} />
<Route path="/dashboard" component={MyAccount} />
<Route path="/register" component={Register} />
<Route path="/login" component={Login} />
</Switch>
</Router>
....
我的 Landing
组件使用 @react-google-maps/api
库有条件地显示 MapContainer
组件:
import { GoogleMap, LoadScript, Marker, InfoWindow } from '@react-google-maps/api';
const containerStyle = {
width: '100%',
height: '400px'
};
const MapComponent = ({ trips }) => {
const [map, setMap] = useState(null);
const [ selected, setSelected ] = useState({});
const [ currentPosition, setCurrentPosition ] = useState({});
const success = position => {
const currentPosition = {
lat: position.coords.latitude,
lng: position.coords.longitude
}
setCurrentPosition(currentPosition);
};
const onSelect = item => {
setSelected(item);
};
const onLoad = useCallback(function callback(map) {
const bounds = new window.google.maps.LatLngBounds();
map.fitBounds(bounds);
setMap(map)
}, []);
const onUnmount = useCallback(function callback(map) {
setMap(null)
}, []);
const getPosition = () => {
return new Promise((res, rej) => {
navigator.geolocation.getCurrentPosition(res, rej);
});
}
const setPositionFromGeolocation = async () => {
const res = await getPosition();
const currentPosition = {
lat: res.coords.latitude,
lng: res.coords.longitude
}
setCurrentPosition(currentPosition);
}
useEffect(() => {
setPositionFromGeolocation();
},[setPositionFromGeolocation]);
return (
<LoadScript
googleMapsApiKey={process.env.REACT_APP_GOOGLE_MAPS_API_KEY}
>
<GoogleMap
mapContainerStyle={containerStyle}
center={currentPosition}
zoom={2}
onLoad={onLoad}
onUnmount={onUnmount}
>
{Array.from(trips).map(trip => {
const position = {
lng: trip.geometry.coordinates[0],
lat: trip.geometry.coordinates[1]
}
return (
<Marker
key={trip._id}
position={position}
onClick={() => onSelect(trip)}
/>
)
})
}
{
selected.geometry && (
<InfoWindow
position={{
lng: selected.geometry.coordinates[0],
lat: selected.geometry.coordinates[1]
}}
clickable={true}
onCloseClick={() => setSelected({})}
>
<p>{selected.description}</p>
</InfoWindow>
)
}
</GoogleMap>
</LoadScript>
);
}
当我改变路线时,我得到这些 errors in console。我相信,这些错误的发生是因为我使用 navigator.geolocation.getCurrentPosition
通过 async/await
语法获取当前用户位置。除了我忘记添加的try/catch,有人可以指出我遗漏了什么或做错了什么吗?
原来,我忘记将 trips
prop 添加到 useEffect
作为依赖项,它正在从 Landing
组件传递到 MapComponent
组件。所以 useEffect
的最终版本应该是这样的:
useEffect(() => {
setPositionFromGeolocation();
},[trips]);