Sign in

Making a basic map based application using React Native (and some Expo)

Nowadays, you can easily build out a nifty mobile app that utilizes a map of some sort. If your go-to language is JavaScript, this can be done using React Native’s map library. This article will provide an overview of how you can get started with your own map-based app.

As a precursor — my recommendation would generally be to use this in tandem with Expo as Expo provides useful tools which allow you to do things like grab your device’s location for mapping and easily test your application.

My group and I used these tools and frameworks to build a Pokemon Go clone where users could see their real time position on a map, see monsters spawn at intervals, and interact with monsters and others users on the map.

Getting started

Install react and react-native-maps and import the libraries. A code snippet like below allows you to render the simplest of maps onto a screen. Incorporating the customMapStyle and provider tags allows you to apply designs which can be created using Google maps — simply generate JSON using the UI and drop it into your own code. initialRegion sets the default view of your map when it loads.

import React, { useState, useEffect } from 'react';
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';
import { View, StyleSheet, Image } from 'react-native';
export default function Map() {
return (
<View style={styles.container}>
<MapView
customMapStyle={require('../assets/map-design.json')}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: 40.704498,
longitude: -74.009499,
latitudeDelta: 1/300,
longitudeDelta: 2/300,
}}
style={styles.mapStyle}
>
// *** Other map elements *** // </MapView>
</View>
)
}

Incorporating location markers

After you’re able to generate a map, the next most useful thing for most folks is likely the ability to drop pins on the map to identify a target location. Fortunately, this feature is something that is built into MapView as well.

A snippet like below allows you drop a pin or a marker onto the map. You’ll notice a few elements here —

  • onPress — Your markers can be interactive. In this particular example, we have an anonymous function which triggers a callback function. By utilizing this capability, you can do things like redirect to a different view, have your database update, etc. upon a click of a marker.
  • Image — The default marker for MapView is a boring old red pin. You can import your own images to use instead (e.g. Pokemon sprites).
<MapView> 
....
{arrayOfLocationObjects.map((eachLocation) => (
<MapView.Marker
onPress={() => onPress(callbackFunction)}
coordinate={{
latitude: eachLocation.latitude,
longitude: eachLocation.longitude,
}}
>
<Image
source={{
uri: eachLocation.locationURI,
style={{width:40, height:40}}
resizeMode="contain"
}}
/>
</MapView.Marker>
))}
</MapView>

Dropping and updating your (and others’) active location on a map

We now know how to drop a pre-identified coordinate onto the map... but what if you want to create the next Google maps where you can actively track changing locations of your apps’ users? Well, that can be made pretty simple too thanks to Expo’s location library.

Let’s look at the (large) code snippet that follows the steps below and walk through what is happening. For additional context here, I’m using functional components (which I recommend 100x over using class components).

  1. In the useEffect hook, we check to see if the user has given the app permissions to grab their device’s location. If the user hasn’t explicitly approved yet, they should receive a pop-up alert asking if they want to grant the app permission
  2. Every 2000 ms, our code requests the user’s current location and passes the response object into the location variable. The response will typically look something like —
{
"coords": Object {
"latitude": 40.7044986,
"longitude": -74.009499,
}
}

3. Whenever the coordinates are refreshed, your marker will re-render on the map view to reflect your (or rather, your device’s) current position

import React, { useState, useEffect } from 'react';
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';
import { View, StyleSheet, Image } from 'react-native';
import * as Location from 'expo-location';
export default function Map({ navigation }) {const [location, setLocation] = useState(null);

useEffect(() => {
async function getLocations() {
let { status } = await Location.requestForegroundPermissionsAsync()
const interval = setInterval(() => {
(async () => {
if (status !== "granted") {
setErrorMsg("Permission to access location was denied")
return
}
let location = await Location.getCurrentPositionAsync({});
setLocation(location);
})();
}, 2000);
}
getLocations();
}, []);
if (location !== null || location !== undefined ) {
return (
<View style={styles.container}>
<MapView
initialRegion={{
latitude: 40.704498,
longitude: -74.009499,
latitudeDelta: 1/300,
longitudeDelta: 2/300
}}
>
<MapView.Marker
coordinate={{
latitude: location.coords.latitude,
longitude: location.coords.longitude
}}
>

And …. that’s it — that’s the basics of making a map based app using React Native. If you’re interested in expanding this feature to things like showing OTHER users’ changing locations on YOUR personal map, you’ll have to explore options like incorporating Socket.IO (which is what we did for our Pokemon Go replica, but this article won’t delve into it).

To give a preview of how you might want to do it though, we would emit the location to a host (we used ngrok) every time we refreshed the user’s location and then continuously pull others’ locations at a set interval in another useEffect hook statement.

const io = require('socket.io-client');
let socket = io.connect(**input server here**);
export default function Map() {
const [friends, setFriends] = useState({});
.....
useEffect(() => {
const interval = setInterval(() => {
(async () => {
.....
socket.emit('position', {
data: location,
id: email
});
useEffect(() => {
const interval = setInterval(() => {
socket.on('otherPositions', (positionsData) => {
tempFriends[positionsData.id] = { ...positionsData };
setFriends({
friends: tempFriends,
});
});
}, 2000);
}, []);

If you’re interested in knowing more about creating a React Native app using maps or about how we went about creating our Pokemon Go clone, feel free to reach out to me on LinkedIn here!