如何在一个组件中处理多个不同的状态更新?

问题描述

我正在使用react-native-mapsexpo-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

Tooltip.js显示每个商店的标记

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 (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...