问题描述
我正在尝试在地图上移动一些标记,但是在更新包含有关它们坐标的信息的数组之后,什么也没发生,只是闪烁而没有移动。
BusMarker.js(客户标记)
import React,{ useState,useEffect } from 'react'
import { Marker } from 'react-native-maps'
const BusMarker = props => {
const { longitude,latitude,plate } = props
const [coordinates] = useState({
longitude: Number(longitude),latitude: Number(latitude)
})
return (
<Marker
key={`bus-${plate}-${new Date().getMilliseconds()}`}
coordinate={coordinates}
image={require('../../img/icon/bus-icon.png')}>
</Marker>
)
}
export default BusMarker
Map.js
import React,useEffect,Fragment,useCallback,useRef } from 'react'
import { StyleSheet,View,Text } from 'react-native'
import { useSelector,usedispatch } from 'react-redux'
import MapView,{ PROVIDER_GOOGLE} from 'react-native-maps'
import BusMarker from './BusMarker'
import { useFocusEffect } from 'react-navigation-hooks'
const Maps = () => {
const [busLocation,setBusLocation] = useState([
{
"plate": "CAR1203","latitude": 0,"longitude": 0,},])
const [region] = useState({
latitude: 0,longitude: 0,latitudeDelta: 0.0143,longitudeDelta: 0.0134,})
const _renderBusesOnMap = busLocation => {
if (busLocation.length > 0) {
return busLocation.map(({ plate,longitude,latitude }) => {
return (
<BusMarker key={plate} plate={plate} longitude={longitude} latitude={latitude} />
)
})
}
}
const updateLocations = () => {
const newPosition = [
{
"plate": "CAR1203","longitude": 1,]
const timeout = setInterval(() => {
setBusLocation(newPosition)
},1000)
}
useEffect(updateLocations,[])
return (
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
initialRegion={region}
showsCompass={false}
showsTraffic={false}
showsIndoors={false}
showsBuildings={false}
showsPointsOfInterest={false}
loadingEnabled={false}
>
{_renderBusesOnMap(busLocation)}
</MapView>
)
}
const styles = StyleSheet.create({
map: {
flex: 1,backgroundColor: '#ffff',height: '100%'
},})
export default Maps
为什么不更新其在地图上的位置?
我在此项目上使用以下版本: React Native:0.60.5 React Native Maps:0.25.0
解决方法
尝试以下方法:
const BusMarker = props => {
const { longitude,latitude,plate } = props;
const coordinates = {
longitude: Number(longitude),latitude: Number(latitude)
};
return (
<Marker
key={`bus-${plate}-${new Date().getMilliseconds()}`}
coordinate={coordinates}
/>
);
};
const Maps = () => {
const [busLocation,setBusLocation] = useState([
{
plate: "CAR1203",latitude: 37.78825,longitude: -122.4324
}
]);
const [region] = useState({
latitude: 37.78825,longitude: -122.4324,latitudeDelta: 0.0922,longitudeDelta: 0.0421
});
const _renderBusesOnMap = busLocation => {
if (busLocation.length > 0) {
return busLocation.map(({ plate,longitude,latitude }) => {
return (
<BusMarker
key={plate}
plate={plate}
longitude={longitude}
latitude={latitude}
/>
);
});
}
};
const updateLocations = () => {
const newPosition = [
{
plate: "CAR1203",latitude: 37.78845,longitude: -122.4424
}
];
const timeout = setInterval(() => {
setBusLocation(newPosition);
},1000);
};
useEffect(updateLocations,[]);
return (
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
initialRegion={region}
showsCompass={false}
showsTraffic={false}
showsIndoors={false}
showsBuildings={false}
showsPointsOfInterest={false}
loadingEnabled={false}
>
{_renderBusesOnMap(busLocation)}
</MapView>
);
};
我认为主要的问题是在coordinates
中设置BusMarker
的方式。无需在那里使用useState
。您可以将coordinates
设置为具有从道具接收的纬度和经度值的对象。
我已经调整了坐标以使其更易于测试。
更新
我将通过解释我对行为的理解来尝试增加此答案。我将通过给出一个更一般的示例进行解释。因此,假设您有这样的代码:
const Component = props => {
const [data,setData] = useState(props);
// ...
现在将props
设置为data
的初始值。
但是useState不会以这种方式更新道具更改。因此,即使道具已更改,data
仍保留最初传递的值。要告诉data
更新道具更改,您可以在useEffect
内使用Component
:
useEffect(() => {
setData(props);
},[props]);
但是,就像我在原始答案中所说的那样,在这种情况下没有理由使用useState
。我们不需要保持Component
的状态与父props
同步,因为我们可以直接使用props
。 因此,请勿使用我提供的useEffect
方法,因为这是不必要的,只是举一个例子。