使用 redux 获取用户位置并将其设置为状态
我有一个反应应用程序,它使用反应传单在地图上显示用户位置。我使用 navigator.geolocation 来获取位置,并在用户允许访问时将其设置为 userData 状态。有时它在地图上显示它,但有时它返回未定义。
redux-action:
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')
}
}
}
reducer:
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
I have a react app which shows the users location on map using react-leaflet. I used navigator.geolocation to get the position and sets it to the userData state when user allows access. Sometimes it is showing it on map but sometimes it is returning undefined.
redux-action :
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')
}
}
}
reducer :
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,
}
}
}
Component which renders map :
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最好将导航器逻辑保留在 redux 之外,一旦获得数据就可以分派它们。
现在,首先您必须提供一些坐标来初始化传单地图,因为 userData 未定义,并且出于同样的原因不渲染标记
收到数据后,您将需要一个额外的组件来将地图视图更改为中心prop 是不可变的。无需经过中心,因为您拥有有关 redux 的信息,因此您可以从那里使用它。
在下面的演示 您可以使用 redux-toolkit 看到所有部分协同工作。
Its better to keep the navigator logic outside redux and once you get the data you can dispatch them.
Now in the first place you have to provide some coords to initialize the leaflet map as userData is undefined and not render the marker for the same reason
After you receive the data you will need an extra comp to change the maps view as center prop is immutable. No need to pass the center as you have that info on redux so you can consume it from there.
In the following demo you can see all the pieces work together using redux-toolkit.