react-native-map-clustering
react-native-map-clustering copied to clipboard
Typescript compile error - animateToRegion method not found on MapView ref
Version: "react-native-map-clustering": "^3.4.2"
Problem:
- When I import the
react-native-map-clustering, Typescript is failing to compile because theanimateToRegionmethod does not exist on the ref objectMapView. - According to the documentation this should exist.
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;
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;
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}>;
};
Use 'mapRef' prop instead 'ref'
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...