自定义标记在坐标更改后不重新渲染
Custom marker not rerendering after coordinates change
我正在尝试在地图上移动一些标记,但在更新包含有关它们坐标的信息的数组后,什么也没有发生,它只是闪烁但没有移动。
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, { useState, 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",
"latitude": 0,
"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
为什么它不更新它在地图上的位置?
我在这个项目中使用了以下版本:
反应本机:0.60.5
反应本机地图: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>
);
};
我认为主要问题是您在 BusMarker
中设置 coordinates
的方式。那里不需要使用 useState
。您可以将 coordinates
设置为具有从 props 接收到的纬度和经度值的对象。
为了方便测试,我调整了坐标。
更新
我会尝试通过解释我对该行为的理解来补充这个答案。我将通过举一个更一般的例子来解释。假设您有这样的代码:
const Component = props => {
const [data, setData] = useState(props);
// ...
现在props
将被设置为data
的初始值。
但是 useState 不会以这种方式更新 props 变化。因此,即使 props 发生了变化,data
仍然保持最初传递的值。要告诉 data
更新道具更改,您可以在 Component
:
中使用 useEffect
useEffect(() => {
setData(props);
}, [props]);
但是就像我在原来的回答中所说的那样,在这种情况下没有理由使用 useState
。我们不需要保持 Component
的状态与父级 props
同步,因为我们可以直接使用 props
。 所以不要使用我给出的 useEffect
方法,因为它没有必要,只是举个例子。
我正在尝试在地图上移动一些标记,但在更新包含有关它们坐标的信息的数组后,什么也没有发生,它只是闪烁但没有移动。
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, { useState, 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",
"latitude": 0,
"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
为什么它不更新它在地图上的位置?
我在这个项目中使用了以下版本: 反应本机:0.60.5 反应本机地图: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>
);
};
我认为主要问题是您在 BusMarker
中设置 coordinates
的方式。那里不需要使用 useState
。您可以将 coordinates
设置为具有从 props 接收到的纬度和经度值的对象。
为了方便测试,我调整了坐标。
更新
我会尝试通过解释我对该行为的理解来补充这个答案。我将通过举一个更一般的例子来解释。假设您有这样的代码:
const Component = props => {
const [data, setData] = useState(props);
// ...
现在props
将被设置为data
的初始值。
但是 useState 不会以这种方式更新 props 变化。因此,即使 props 发生了变化,data
仍然保持最初传递的值。要告诉 data
更新道具更改,您可以在 Component
:
useEffect
useEffect(() => {
setData(props);
}, [props]);
但是就像我在原来的回答中所说的那样,在这种情况下没有理由使用 useState
。我们不需要保持 Component
的状态与父级 props
同步,因为我们可以直接使用 props
。 所以不要使用我给出的 useEffect
方法,因为它没有必要,只是举个例子。