#reactjs #react-native #google-maps #google-maps-markers #react-native-maps
#reactjs #react-native #google-карты #google-карты-маркеры #react-native-maps
Вопрос:
Я пытаюсь переместить некоторые маркеры по карте, но после обновления массива, который содержит информацию о их координатах, ничего не происходит, он просто мигает, но не перемещается.
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
Почему он не обновляет свое местоположение на карте?
В этом проекте я использую следующие версии: React Native: 0.60.5 Карты React Native: 0.25.0
Ответ №1:
Попробуйте это вместо:
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
в качестве объекта значения широты и долготы, которые вы получаете из props.
Я скорректировал координаты, чтобы упростить тестирование.
Обновить
Я попытаюсь добавить к этому ответу, объяснив мое понимание поведения. Я объясню, приведя более общий пример. Итак, допустим, у вас есть код, подобный этому:
const Component = props => {
const [data, setData] = useState(props);
// ...
Теперь props
будет установлено начальное значение data
.
Но useState не будет обновляться при изменении реквизита таким образом. Таким образом, даже если реквизиты изменились, data
по-прежнему сохраняется значение, которое было передано изначально. Чтобы сообщить data
об обновлении при изменении реквизита, вы могли бы использовать useEffect
inside Component
:
useEffect(() => {
setData(props);
}, [props]);
Но, как я уже сказал в своем первоначальном ответе, в этой ситуации нет причин использовать useState
. Нам не нужно синхронизировать состояние Component
с родительским, props
поскольку мы можем просто использовать props
напрямую. Поэтому не используйте приведенный мной useEffect
подход, поскольку в нем нет необходимости, это просто для примера.
Комментарии:
1. Это работает! БОЛЬШОЕ ВАМ СПАСИБО! Не могли бы вы объяснить мне, почему он выполняет повторный запуск с помощью useState?
2. Я обновил свой ответ и попытался дать объяснение того, что, по моему мнению, происходит.