【问题标题】:React useEffect avoid update callback in every updateReact useEffect 避免每次更新中的更新回调
【发布时间】:2020-10-19 03:08:28
【问题描述】:

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

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

当前行为

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

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

预期行为

  1. 仅订阅一次 geofire 并接收位置(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;

【问题讨论】:

  • [locationInfo] with this option the update does not work 是什么意思?因为那将是正确的方法。通过将currentLocation 作为一个部门,您正在更新currentLocation,这会再次触发它并导致无限循环

标签: javascript reactjs use-effect geofire


【解决方案1】:

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

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

然后我注意到您通过异步回调更新状态,这可能与它有关。不亲眼看到就很难说。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 2019-03-11
    • 2020-10-26
    • 2021-10-16
    • 1970-01-01
    相关资源
    最近更新 更多