react-native-map-clustering icon indicating copy to clipboard operation
react-native-map-clustering copied to clipboard

Typescript compile error - animateToRegion method not found on MapView ref

Open jacky-lam opened this issue 4 years ago • 4 comments

Version: "react-native-map-clustering": "^3.4.2"

Problem:

  • When I import the react-native-map-clustering, Typescript is failing to compile because the animateToRegion method does not exist on the ref object MapView.
  • According to the documentation this should exist.
Screenshot 2021-06-27 at 21 35 06

Basic example of whole code below:

import React from 'react';
import { StyleSheet, SafeAreaView } from 'react-native';
import MapView from 'react-native-map-clustering';
import { Marker } from 'react-native-maps';

const style = StyleSheet.create({
  map: {
    width: '100%',
    height: '100%',
  },
});

const defaultLatitudeDelta = 0.025;
const defaultLongitudeDelta = 0.025;
const initialLatitude = 51.5074;
const initialLongitude = 0.1278;

const TestScreen: React.FC = () => {
  const mapRef = React.useRef<MapView>();

  React.useEffect(() => {
    mapRef.current?.animateToRegion({
      latitude: initialLatitude + 0.001,
      longitude: initialLongitude + 0.001,
      latitudeDelta: defaultLatitudeDelta,
      longitudeDelta: defaultLongitudeDelta,
    });
  });

  return (
    <SafeAreaView>
      <MapView
        style={style.map}
        initialRegion={{
          latitude: initialLatitude,
          longitude: initialLongitude,
          latitudeDelta: defaultLatitudeDelta,
          longitudeDelta: defaultLongitudeDelta,
        }}
      >
        <Marker
          coordinate={{
            latitude: initialLatitude,
            longitude: initialLongitude,
          }}
        />
        <Marker
          coordinate={{
            latitude: initialLatitude + 0.001,
            longitude: initialLongitude,
          }}
        />
      </MapView>
    </SafeAreaView>
  );
};

export default TestScreen;

jacky-lam avatar Jun 27 '21 20:06 jacky-lam

For those who are seeking for a get-around.

I managed to hack around it by tricking the Typescript compiler:

import React from 'react';
import { StyleSheet, SafeAreaView } from 'react-native';
import MapView from 'react-native-map-clustering';
import { Marker, default as MapView2 } from 'react-native-maps';

const style = StyleSheet.create({
  map: {
    width: '100%',
    height: '100%',
  },
});

const defaultLatitudeDelta = 0.025;
const defaultLongitudeDelta = 0.025;
const initialLatitude = 51.5074;
const initialLongitude = 0.1278;

const TestScreen: React.FC = () => {
  const mapRef = React.useRef<MapView>();

  React.useEffect(() => {
    if (mapRef.current) {
      const hackMap = mapRef.current as MapView2;
      hackMap.animateToRegion({
        latitude: initialLatitude + 0.001,
        longitude: initialLongitude + 0.001,
        latitudeDelta: defaultLatitudeDelta,
        longitudeDelta: defaultLongitudeDelta,
      });
    }
  });

  return (
    <SafeAreaView>
      <MapView
        style={style.map}
        initialRegion={{
          latitude: initialLatitude,
          longitude: initialLongitude,
          latitudeDelta: defaultLatitudeDelta,
          longitudeDelta: defaultLongitudeDelta,
        }}
      >
        <Marker
          coordinate={{
            latitude: initialLatitude,
            longitude: initialLongitude,
          }}
        />
        <Marker
          coordinate={{
            latitude: initialLatitude + 0.001,
            longitude: initialLongitude,
          }}
        />
      </MapView>
    </SafeAreaView>
  );
};

export default TestScreen;

jacky-lam avatar Jul 03 '21 12:07 jacky-lam

You can get around renaming default buy just doing:

import React from 'react';
import MapView from 'react-native-map-clustering';
import Map, { Marker } from 'react-native-maps';

const TestScreen: React.FC = () => {
  const mapRef = React.useRef<Map>();

  React.useEffect(() => {
      mapRef.current?.animateToRegion();
    }
  }, []);

  return <MapView ref={mapRef}>;
};

markrickert avatar Sep 06 '21 19:09 markrickert

Use 'mapRef' prop instead 'ref'

AstanyTR avatar Jul 06 '22 15:07 AstanyTR

I still think there's an issue with TS and this libraries mapRef Typing...i created: https://github.com/venits/react-native-map-clustering/issues/245

Here is what I have found to work:

interface ProviderProps {
  mapRef: MutableRefObject<MapView | null>;
}

const ClusterMapProvider = () => {
  const mapRef = useRef<MapView>(null);

return <ClusterMapContext.Provider>{children}</ClusterMapContext.Provider>;
}

const Component = () => {
  const { mapRef  } = useClusterMapContext();

return (
    <MapView
      ref={mapRef}
      {...rest}
    >
      {markers && clusters}
    </MapView>
  );
}

But it definitely wasn't clear...

lucksp avatar Sep 29 '22 17:09 lucksp