Unlock the Power of Location-Based Features in Your React Native App
What is React Native Maps?
React Native Maps is a component system that ships with platform-native code, allowing you to compile it together with React Native. This library provides fundamental components like <MapView />
and <Marker>
to help you create stunning map-based features.
Getting Started with React Native Maps
To get started, you’ll need to obtain an API key to incorporate Google Maps functionality into your app. Follow these steps to procure your API secrets:
- …
Then, add the following code block to android/app/src/main/AndroidManifest.xml
to connect your SDK key to the React Native project:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_API_KEY"/>
Next, install react-native-maps
in your project using the following command:
npm install react-native-maps
Setting Up the Map Default View
Remove all default code from the App.js
file and import the <MapView />
component from react-native-maps
. Render the <MapView />
component and specify the initial region using the initialRegion
prop. Don’t forget to add the style
property to set the dimensions; otherwise, you’ll end up with a white screen.
import React from 'eact';
import { View, StyleSheet } from 'eact-native';
import MapView, { Marker } from 'eact-native-maps';
const App = () => {
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
map: {
flex: 1,
},
});
Using React Native Maps with the useState Hook
To change the region dynamically, use the onRegionChangeComplete
prop to set the new region into the state. This callback prop runs when the user stops panning around the map.
import React, { useState } from 'eact';
import { View, StyleSheet } from 'eact-native';
import MapView, { Marker } from 'eact-native-maps';
const App = () => {
const [region, setRegion] = useState({
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
});
const handleRegionChangeComplete = (newRegion) => {
setRegion(newRegion);
};
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={region}
onRegionChangeComplete={handleRegionChangeComplete}
/>
</View>
);
};
Adding a Marker in React Native Maps
Import the Marker
component from react-native-maps
and render it as a child of <MapView />
. Pass the coordinate for the marker in the coordinate
prop. You can add multiple markers to the map and pass them as direct children to the <MapView />
component.
import React from 'eact';
import { View, StyleSheet } from 'eact-native';
import MapView, { Marker } from 'eact-native-maps';
const App = () => {
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
<Marker
coordinate={{
latitude: 37.78825,
longitude: -122.4324,
}}
/>
</MapView>
</View>
);
};
Customizing the Map Marker
Change the marker color using the pinColor
prop or add a custom marker image by passing the image
prop to the <Marker />
component. You can also use custom marker views to indicate locations using symbols.
import React from 'eact';
import { View, StyleSheet } from 'eact-native';
import MapView, { Marker } from 'eact-native-maps';
const App = () => {
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
<Marker
coordinate={{
latitude: 37.78825,
longitude: -122.4324,
}}
pinColor="blue"
image={require('./custom-marker.png')}
/>
</MapView>
</View>
);
};
Styling the Map
Generate a JSON object to design the map using the Google style generator. Then, pass the generated style object to the customMapStyle
prop of the <MapView />
component. This will change the map style from the default light theme to a dark theme.
import React from 'eact';
import { View, StyleSheet } from 'eact-native';
import MapView, { Marker } from 'eact-native-maps';
const App = () => {
const mapStyle = [
{
elementType: 'geometry',
stylers: [
{
color: '#242f3e',
},
],
},
{
elementType: 'labels.text.stroke',
stylers: [
{
color: '#242f3e',
},
],
},
{
elementType: 'labels.text.fill',
stylers: [
{
color: '#746855',
},
],
},
{
featureType: 'administrative.locality',
elementType: 'labels.text.fill',
stylers: [
{
color: '#d59563',
},
],
},
{
featureType: 'poi',
elementType: 'labels.text.fill',
stylers: [
{
color: '#d59563',
},
],
},
{
featureType: 'poi.park',
elementType: 'geometry',
stylers: [
{
color: '#263c3f',
},
],
},
{
featureType: 'poi.park',
elementType: 'labels.text.fill',
stylers: [
{
color: '#6b9a76',
},
],
},
{
featureType: 'road',
elementType: 'geometry',
stylers: [
{
color: '#38414e',
},
],
},
{
featureType: 'road',
elementType: 'geometry.stroke',
stylers: [
{
color: '#212a37',
},
],
},
{
featureType: 'road',
elementType: 'labels.text.fill',
stylers: [
{
color: '#9ca5b3',
},
],
},
{
featureType: 'road.highway',
elementType: 'geometry',
stylers: [
{
color: '#746855',
},
],
},
{
featureType: 'road.highway',
elementType: 'geometry.stroke',
stylers: [
{
color: '#1f2835',
},
],
},
{
featureType: 'road.highway',
elementType: 'labels.text.fill',
stylers: [
{
color: '#f3d19c',
},
],
},
{
featureType: 'transit',
elementType: 'geometry',
stylers: [
{
color: '#2f3948',
},
],
},
{
featureType: 'transit.station',
elementType: 'labels.text.fill',
stylers: [
{
color: '#d59563',
},
],
},
{
featureType: 'water',
elementType: 'geometry',
stylers: [
{
color: '#17263c',
},
],
},
{
featureType: 'water',
elementType: 'labels.text.fill',
stylers: [
{
color: '#515c6d',
},
],
},
{
featureType: 'water',
elementType: 'labels.text.stroke',
stylers: [
{
color: '#17263c',
},
],
},
];
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
customMapStyle={mapStyle}
/>
</View>
);
};
Getting the Current Location or a Specific Coordinate
To animate to a particular coordinate, create a reference to <MapView />
using the useRef()
Hook. Then, use the animateToRegion()
method to control the MapView
component.
import React, { useRef } from 'eact';
import { View, StyleSheet } from 'eact-native';
import MapView, { Marker } from 'eact-native-maps';
const App = () => {
const mapViewRef = useRef(null);
const handlePress = () => {
mapViewRef.current.animateToRegion({
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
});
};
return (
<View style={styles.container}>
<MapView
ref={mapViewRef}
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
<Button title="Animate to coordinate" onPress={handlePress} />
</View>
);
};
Using <Polyline />
in React Native Maps
Create lines between multiple coordinates using the <Polyline />
component from react-native-maps
. Pass an array of coordinates in the coordinates
prop and specify additional props for styling purposes.
import React from 'eact';
import { View, StyleSheet } from 'eact-native';
import MapView, { Polyline } from 'eact-native-maps';
const App = () => {
const coordinates = [
{
latitude: 37.78825,
longitude: -122.4324,
},
{
latitude: 37.79625,
longitude: -122.4424,
},
{
latitude: 37.80425,
longitude: -122.4524,
},
];
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
<Polyline
coordinates={coordinates}
strokeColor="blue"
strokeWidth={5}
/>
</MapView>
</View>
);
};
Using the Google Maps Direction API
To draw lines that take into account actual geographical paths and roads, use the Google Maps Direction API. Enable the API for your project, then create a helper function to get directions. This will return all possible routes between two places.
import React, { useState, useEffect } from 'eact';
import { View, StyleSheet } from 'eact-native';
import MapView, { Polyline } from 'eact-native-maps';
const App = () => {
const [directions, setDirections] = useState(null);
useEffect(() => {
const getDirections = async () => {
const response = await fetch(
`https://maps.googleapis.com/maps/api/directions/json?origin=37.78825,-122.4324&destination=37.79625,-122.4424&mode=driving&key=YOUR_API_KEY`
);
const data = await response.json();
setDirections(data.routes[0].overview_polyline.points);
};
getDirections();
}, []);
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
{directions && (
<Polyline
coordinates={decodePolyline(directions)}
strokeColor="blue"
strokeWidth={5}
/>
)}
</MapView>
</View>
);
};
const decodePolyline = (polylineString) => {
const polylineArray = polylineString.split(',');
const coordinates = [];
for (let i = 0; i < polylineArray.length; i += 2) {
coordinates.push({
latitude: parseFloat(polylineArray[i]),
longitude: parseFloat(polylineArray[i + 1]),
});
}
return coordinates;
};