使用 redux 获取用户位置并将其设置为状态
Getting user location and setting it to state using redux
我有一个 React 应用程序,它使用 react-leaflet 在地图上显示用户位置。我使用 navigator.geolocation 获取位置并在用户允许访问时将其设置为 userData 状态。有时它在地图上显示它但有时它返回未定义。
redux 动作:
export const getUserData = () => {
return async (dispatch) => {
if(navigator.geolocation) {
navigator.geolocation.watchPosition((position) => {
dispatch({
type: FETCH_USER_DATA,
payload: position.coords
})
})
} else {
alert('Unable to get location')
}
}
}
减速机:
export const rootReducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_IP_LOCATION:
return {
...state,
ipLocation: action.payload,
isLoading: false,
}
case FETCH_USER_DATA:
return {
...state,
userData: action.payload,
isLoading: false,
}
}
}
渲染地图的组件:
import React from 'react';
import '../styles/MapComponent.css';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import { useEffect } from 'react';
import { getUserData } from '../redux/action/';
import { useDispatch, useSelector } from 'react-redux'
const MapComponent = () => {
const dispatch = useDispatch()
const isLoading = useSelector((state) => state.isLoading)
const coord = useSelector((state) => state.userData)
useEffect(() => {
dispatch(getUserData())
}, [])
return (
<MapContainer center={[coord.latitude, coord.longitude]} zoom={12}>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={[coord.latitude, coord.longitude]}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
)
}
export default MapComponent
最好将导航器逻辑放在 redux 之外,一旦获得数据就可以调度它们。
useEffect(() => {
if (navigator?.geolocation) {
navigator.geolocation.getCurrentPosition((location) => {
if (location) dispatch(getUserData(location.coords));
});
}
}, []);
现在首先你必须提供一些坐标来初始化传单地图,因为 userData 是未定义的,并且出于同样的原因不渲染标记
收到数据后,您将需要额外的补偿来更改地图视图,因为中心道具是不可变的。无需通过中心,因为您在 redux 上有该信息,因此您可以从那里使用它。
function ChangeView() {
const coords = useSelector((state) => state.root.userData);
const map = useMap();
map.setView([coords.latitude, coords.longitude], zoom);
return null;
}
在下面的 demo 中,您可以看到所有部分都使用 redux-toolkit 协同工作。
我有一个 React 应用程序,它使用 react-leaflet 在地图上显示用户位置。我使用 navigator.geolocation 获取位置并在用户允许访问时将其设置为 userData 状态。有时它在地图上显示它但有时它返回未定义。
redux 动作:
export const getUserData = () => {
return async (dispatch) => {
if(navigator.geolocation) {
navigator.geolocation.watchPosition((position) => {
dispatch({
type: FETCH_USER_DATA,
payload: position.coords
})
})
} else {
alert('Unable to get location')
}
}
}
减速机:
export const rootReducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_IP_LOCATION:
return {
...state,
ipLocation: action.payload,
isLoading: false,
}
case FETCH_USER_DATA:
return {
...state,
userData: action.payload,
isLoading: false,
}
}
}
渲染地图的组件:
import React from 'react';
import '../styles/MapComponent.css';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import { useEffect } from 'react';
import { getUserData } from '../redux/action/';
import { useDispatch, useSelector } from 'react-redux'
const MapComponent = () => {
const dispatch = useDispatch()
const isLoading = useSelector((state) => state.isLoading)
const coord = useSelector((state) => state.userData)
useEffect(() => {
dispatch(getUserData())
}, [])
return (
<MapContainer center={[coord.latitude, coord.longitude]} zoom={12}>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={[coord.latitude, coord.longitude]}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
)
}
export default MapComponent
最好将导航器逻辑放在 redux 之外,一旦获得数据就可以调度它们。
useEffect(() => {
if (navigator?.geolocation) {
navigator.geolocation.getCurrentPosition((location) => {
if (location) dispatch(getUserData(location.coords));
});
}
}, []);
现在首先你必须提供一些坐标来初始化传单地图,因为 userData 是未定义的,并且出于同样的原因不渲染标记
收到数据后,您将需要额外的补偿来更改地图视图,因为中心道具是不可变的。无需通过中心,因为您在 redux 上有该信息,因此您可以从那里使用它。
function ChangeView() { const coords = useSelector((state) => state.root.userData); const map = useMap(); map.setView([coords.latitude, coords.longitude], zoom); return null; }
在下面的 demo 中,您可以看到所有部分都使用 redux-toolkit 协同工作。