问题描述
我正在使用react-native-maps
和expo-location
构建移动地图应用。
该应用程序每秒读取一次用户的电话位置,从用户所在位置附近商店中的服务器获取信息,并根据服务器的响应在地图上显示带有标记的地图。 当检测到按下标记时,它将打开工具提示,其中包含标记数据的模态。
问题:单击标记时,它将更新Home.js中的TooltipData状态,以便将其发送到Tooltip.js组件子级。 因为我每秒要从服务器获取数据并更新Home.js中的状态,所以当用户在商店更新Home.js状态时按下标记时,该应用程序会因为同时发生2个状态更新而中断
我在应用中使用Redux,所以我认为我可以将TooltipData存储在Redux存储中?
home.js
,其中所有内容都居中:
import React,{useState,useEffect} from "react";
import {StyleSheet} from 'react-native'
import { Map,OfflineMap,ToolTip,ServiceProviderMarker } from "../../components/maps";
import { Foundation } from "@expo/vector-icons";
import {useLocation} from '../../hooks'
import {getServiceProviders} from '../../api/wrappers/locationService'
import { locationConfig } from "../../config";
const Home = (props) => {
const [{coords},err ] = useLocation(true)
const [serviceProviders,setServiceProviders] = useState([])
const [isLocation,setIsLocation] = useState(false)
const [toolTipData,setToolTipData] = useState({
data:{},isActive: false,})
useEffect(() => {
if(!coords || err ){
setIsLocation(false)
} else{
setIsLocation(true)
getServiceProviders({
Latitude:coords.latitude,Longitude:coords.longitude,Radius:locationConfig.radius,MeasureUnit:locationConfig.measureUnit(0)
})
.then((res) => setServiceProviders(res))
.catch((err) => console.log(err));
}
},[coords,err]);
const handletoolTip = (visibilty,data={} ) => {
setToolTipData(prevstate=>({...prevstate,isActive:visibilty,data:{ ...data}}))
}
return (
isLocation
?
<Map style={styles.map} location={ coords}>
<ServiceProviderMarker
serviceProviders={serviceProviders || []}
onToolTip={(visibilty,data)=> handletoolTip(visibilty,data)}
/>
<ToolTip
visible={toolTipData.isActive}
providerData={toolTipData.data}
hidetoolTip={()=>setToolTipData({...toolTipData,isActive:false})}
/>
</Map>
:
<OfflineMap style={styles.map}/>
);
};
Home.navigationoptions = {
title: "Find",tabBarIcon: <Foundation name="target-two" size={20} />,};
const styles = StyleSheet.create({
map:{
flex:1
}
})
export default Home;
Map.js
import React from "react";
import { StyleSheet } from "react-native";
import MapView,{Circle,Marker} from 'react-native-maps'
import { locationConfig } from '../../config'
const Map = ({children,location}) => {
return (
<MapView
style={styles.map}
initialRegion={{
...location,...locationConfig.initDeltaCoords
}}>
<Marker pinColor='#FFD700' coordinate={location} title='Consumer'/>
<Circle center={location} radius={locationConfig.radius}/>
{children}
</MapView>
);
};
const styles = StyleSheet.create({
map: {
flex: 1,},});
export default Map;
ServiceproviderMarker.js
import React from 'react'
import {Marker} from 'react-native-maps'
const ServiceProviderMarker = ({serviceProviders,onToolTip}) => {
return(
serviceProviders.map((provider,i)=>(
<Marker
key={i}
coordinate={{
latitude: provider.Location.Latitude,longitude:provider.Location.Longitude
}}
pinColor={"#ffd1dc"}
onPress={()=>{
console.log('marker pressed')
onToolTip(true,{
profession:provider.Profession,title:provider.Title,firstName:provider.FirstName,lastName:provider.LastName,description:provider.Description,rating:provider.rating
})
}}
/>
))
)
}
export default ServiceProviderMarker
import React from 'react'
import {StyleSheet,View,Image} from 'react-native'
import {Modal,Text,Button} from '@ui-kitten/components'
const ToolTip = ({visible,providerData,hidetoolTip}) => {
if(!providerData || providerData === {}){
return(
<Text>Sorry There is no data for this provider</Text>
)
}
return (
<Modal visible={visible} style={styles.model} onBackdropPress={hidetoolTip} backdropStyle={styles.backdropStyle}>
<Text>{providerData.firstName} {providerData.lastName}</Text>
<Button onPress={hidetoolTip}>Hide</Button>
</Modal>
)
}
const styles = StyleSheet.create({
model:{
height:'60%',width:'80%',justifyContent:'center',alignItems:'center',backgroundColor:'red',borderWidth:3
},backdropStyle:{
backgroundColor:'rgba(0,0.6)'
}
})
export default ToolTip
要获取用户位置,我使用了自定义钩子useLocation.js
:
import { useState,useEffect } from "react";
import {
Accuracy,requestPermissionsAsync,watchPositionAsync,} from "expo-location";
import {locationConfig} from '../config'
const shallowEqualLocation = (object1,object2) => {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);
if (keys1.length !== keys2.length) {
return false;
}
for (let key of keys1) {
if (object1[key] !== object2[key]) {
return false;
}
}
return true;
}
const useLocation = (shouldTrack) => {
const [err,setErr] = useState(null);
const [location,setLocation] = useState({})
const watchPositionoption = {
accuracy: Accuracy.BestForNavigation,timeInterval: locationConfig.getLocationInterval,distanceInterval: locationConfig.getdistanceInterval,}
useEffect(() => {
let subscriber;
const startWatching = async () => {
try {
const { granted } = await requestPermissionsAsync();
if (!granted) {
throw new Error("Location Permissions not granted");
}
subscriber = await watchPositionAsync(
watchPositionoption,(newLocation)=>{setLocation(newLocation)}
);
} catch (e) {
setErr(e);
}
};
if (shouldTrack) {
startWatching();
} else {
if (subscriber) subscriber.remove();
subscriber = null;
}
return () => {
if (subscriber) subscriber.remove();
};
},[shouldTrack,location]);
return [location,err];
};
export default useLocation
感谢您的时间。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)