React useEffect 避免每次更新中的更新回调



有没有办法避免在useEffect中更新回调?例如,我订阅了一个带有 geofire 的事件,它会侦听更改并接收位置。

我需要更新我的状态,而无需每次更新都订阅。

当前行为

  1. 订阅地火和接收位置 (A(
  2. 使用新位置更新我的状态 (A(
  3. 再次订阅地火并接收位置 (A(

这是一个无限循环。而且我无法接收其他位置

预期行为

  1. 仅订阅一次地火并接收位置(A,B,C(
  2. 使用新位置(A,B,C(更新我的州

import React, {useState, useEffect} from 'react';
import {View, Text} from 'react-native';
import {GeoPosition, GeoError} from 'react-native-geolocation-service';
import {getCurrentLocation, LocationInfo} from '../../util/geolocation';
import GeoFireService, {EVENT_TYPE} from './services/GeoFireService';
interface CurrentLocation {
[key: string]: {
location: [number, number];
distance: number;
};
}
const Ads = () => {
const [locationInfo, setLocationInfo] = useState({
latitude: 0,
longitude: 0,
altitude: 0,
accuracy: 0,
} as LocationInfo);
const [currentLocation, setCurrentLocation] = useState({});
// set the current location
useEffect(() => {
getCurrentLocation(
(position: GeoPosition) => {
const {latitude, longitude, accuracy, altitude} = position.coords;
setLocationInfo({latitude, longitude, accuracy, altitude});
},
(err: GeoError) => {
console.log(err);
},
);
}, []);
// get ads
useEffect(() => {
(async () => {
if (locationInfo.latitude === 0 && locationInfo.longitude === 0) {
return null;
}
// this must be execute only once
await GeoFireService.queryToRadius(
[-34.5742746, -58.4744191],
30,
(key: string, location: [number, number], distance: number,) => {
// update state 
setCurrentLocation({
...currentLocation,
[key]: {location},
});
},
);
})();
}, [locationInfo, currentLocation]);
// [locationInfo] with this option the update does not work
return (
<View>
<Text>
Latitude: {locationInfo.latitude} Longitude: {locationInfo.longitude}
</Text>
{Object.keys(currentLocation).map((key: string) => (
<Text key={key}>Ubicacion: {currentLocation[key].location}</Text>
))}
</View>
);
};
export default Ads;

您是否检查过返回条件是否在页面加载时起作用(只需在其中放置控制台日志(?

从阅读它来看,似乎两个 useEffects 都在页面加载时被调用,但第二个应该立即退出,然后在第一个完成后再次调用。

然后我注意到你通过异步回调更新状态,这可能与它有关。很难说没有看到它的实际效果。

我会说尝试用函数而不是对象重写你的setCurrentLocation:

setCurrentLocation((currentLocation) => ({
...currentLocation,
[key]: {location},
}));

也许它没有通过并在新旧数据之间切换。

最新更新