reactjs - 坐标更改后自定义标记不重新渲染
问题描述
我正在尝试在地图上移动一些标记,但是在更新包含有关它们的坐标信息的数组之后,没有任何反应,它只是在闪烁,但没有移动。
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
地图.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 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 不会以这种方式更新 props 更改。因此,即使 props 发生了变化,data
它仍然保持最初传递的值。要告诉data
更新道具更改,您可以useEffect
在里面使用Component
:
useEffect(() => {
setData(props);
}, [props]);
但是就像我在原始答案中所说的那样,没有理由useState
在这种情况下使用。我们不需要让Component
's 的状态与父级保持同步,props
因为我们可以直接使用props
。所以不要使用useEffect
我给出的方法,因为它是不必要的,只是举个例子。
推荐阅读
- jmeter - 如何在 JSR223 采样器中使用 StringFromFile 函数?
- python-3.x - 用 x =df2.index .values, y = df2.coulmn.values 散点图
- java - Android 中的错误:android.view.InflateException:二进制 XML 文件第 49 行:膨胀类错误
- scala - 并行执行 Monix 任务
- azure-devops - 如何在多阶段 YAML 管道中添加部署前和部署后批准?
- javascript - 我在我的 React Native 应用程序中获取 Api 时遇到问题
- java - 停止在自定义 Azure-VM 中运行的 Java 进程
- xml - XSLT 1.0 Muenchian 分组实现不起作用
- android - 触发另一个小部件时使小部件可见
- php - 为什么加载 .env 文件的代码位于 bootstrap.php 中?