React useEffect avoid update callback in every update

为君一笑 提交于 2021-01-28 21:46:42

问题


Is there a way to avoid update a callback in useEffect?. For example I am subscribed an event with geofire, this listens for changes and receive locations.

I need to update my state without subscribing every time on every update.

Current behavior

  1. Subscribed to geofire and receive location (A)
  2. Update my state with the new location (A)
  3. Subscribed to geofire again and receive location (A)

this is an infinite loop. And I can't receive the other locations

Expected behavior

  1. subscribed to geofire only once and receive locations (A,B,C)
  2. update my state with the new locations (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;


回答1:


Have you checked if the return conditional is working on page load (just put a console log in there)?

From reading it, it seems both useEffects get called on page load, but the second one should exit immediately, and then get called again after the first one completes.

Then I notice you update state through an async call back, which may have something to do with it. It's difficult to say without seeing it in action.

I would say try rewriting your setCurrentLocation with a function rather than object:

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

Maybe its not getting passed through and toggling between new and old data.



来源:https://stackoverflow.com/questions/62629902/react-useeffect-avoid-update-callback-in-every-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!