Every refresh on my app the map changes the initial position [react-native]

Viewed 759

I'm studying React and i'm coding some Uber features as Maps, Geolocation and Directions using it respective libs. I've been a issue about MapView, i guess ... Everytime when my app is reloaded the initial coords sets to another position on the map with zoom in. I saw another devs have the same problem, although they was using Class Component and I don't know well how to convert the showed solutions to Functional Component. Can anyone help me, please?

that's my code:

const Map = () => {
  const [origin, setOrigin] = useState([0, 0]);
  const [destination, setDestination] = useState([0, 0]);

  const mapView = useRef(null);

  useEffect(() => {
    async function loadPosition() {
      await RNLocation.requestPermission({
        ios: 'whenInUse',
        android: {
          detail: 'coarse',
        },
      }).then(granted => {
        if (!granted) {
          Alert.alert('Não foi permitido o uso da localização');
        }
      });

      const currentOrigin = await RNLocation.getLatestLocation({
        timeout: 2000,
      });
      const {latitude, longitude} = currentOrigin;

      console.log([latitude, longitude]);
      setOrigin([latitude, longitude]);
    }

    loadPosition();
  }, []);

  const handleLocationSelected = useCallback((data, {geometry}) => {
    const {
      location: {lat: latitude, lng: longitude},
    } = geometry;

    const currentDestination = [latitude, longitude];
    setDestination(currentDestination, {
      title: data.structured_formatting.main_text,
    });
  }, []);

  return (
    <View style={{flex: 1}}>
      <MapView
        style={{flex: 1}}
        initialRegion={{
          latitude: origin[0],
          longitude: origin[1],
          latitudeDelta: 0.0143,
          longitudeDelta: 0.0134,
        }}
        showsUserLocation
        loadingEnabled
        ref={mapView}>
        {destination && (
          <Directions
            origin={{
              latitude: origin[0],
              longitude: origin[1],
            }}
            destination={{
              latitude: destination[0],
              longitude: destination[1],
            }}
            onReady={result =>
              mapView.current.fitToCoordinates(result.coordinates)
            }
          />
        )}
      </MapView>
      <Search onLocationSelected={handleLocationSelected} />
    </View>
  );
};
1 Answers

You need to show your Map only after all the coordinations are set. This happens because when you reload the App some contents are already rendered while your requisition are still being requested.

Try the following code:

const Map = () => {
    const [isLoading, setIsLoading] = useState(false);
    const [origin, setOrigin] = useState([0, 0]);
    const [destination, setDestination] = useState([0, 0]);

    const mapView = useRef(null);

    async function loadPosition() {
        setIsLoading(true)

        await RNLocation.requestPermission({
            ios: 'whenInUse',
            android: {
                detail: 'coarse',
            },
        }).then(granted => {
            if (!granted) {
                Alert.alert('Não foi permitido o uso da localização');
            }
        });

        const currentOrigin = await RNLocation.getLatestLocation({
            timeout: 6000,
        });
        const { latitude, longitude } = currentOrigin;

        setOrigin([latitude, longitude]);

        setIsLoading(false)
    }

    const handleLocationSelected = useCallback((data, { geometry }) => {
        const {
            location: { lat: latitude, lng: longitude },
        } = geometry;

        const currentDestination = [latitude, longitude];
        setDestination(currentDestination, {
            title: data.structured_formatting.main_text,
        });
    }, []);


    useEffect(() => {
        loadPosition();
    }, []);

    return (
        <View style={{ flex: 1 }}>
            {isLoading ? (
                <Text> Loading the Map...</Text>
            ) : (
                    <>
                        <MapView
                            style={{ flex: 1 }}
                            initialRegion={{
                                latitude: origin[0],
                                longitude: origin[1],
                                latitudeDelta: 0.0143,
                                longitudeDelta: 0.0134,
                            }}
                            showsUserLocation
                            loadingEnabled
                            ref={mapView}>
                            {destination && (
                                <Directions
                                    origin={{
                                        latitude: origin[0],
                                        longitude: origin[1],
                                    }}
                                    destination={{
                                        latitude: destination[0],
                                        longitude: destination[1],
                                    }}
                                    onReady={result =>
                                      mapView.current.fitToCoordinates(result.coordinates)
                                    }
                                />
                            )}
                        </MapView>
                        <Search onLocationSelected={handleLocationSelected} />
                    </>
                )}
        </View>
    );
};
Related