Introduction to Mapbox and React

·

11 min read

Introduction to Mapbox and React

This post is part of the forthcoming Mapbox Developer's Handbook - a comprehensive guide for anyone building interactive maps and applications using Mapbox. You can pick up a copy here!

What You Will Learn

This post is intended to serve as a guide on how to get up and running with Mapbox GL JS and React. It will walk you through how to create a basic React map component and how to add some common customizations to the map. By the end of this guide you will be able to create a basic fullscreen interactive map using Mapbox GL JS and React.

Prerequisites

  • basic familiarity with React

Introduction to Mapbox

If you are already familiar with Mapbox, go ahead and skip ahead to Application Setup. In short, Mapbox is a powerful platform that provides the building blocks for building map and location-driven applications for the web, mobile, and AR. A lot of the mapping experiences you come across in the wild are likely powered in some capacity by Mapbox (i.e. Strava, New York Times, Shopify, Square). Their main product offerings are:

  • Maps: Brilliant map styles and SDKs for interacting with them
  • Navigation: Powerful routing engine for developing navigation experiences
  • Search: Geocoding service
  • Studio: Powerful UI for developing custom maps and visualizations
  • Vision: Suite of tools centered around leveraging cameras and AI
  • Data: Robust datasets including boundaries, traffic, and movement data

This series will focus on their Maps and Studio products. Hoping I get a chance to dig into some of their other offerings like Navigation, Vision, and Search down the road though.

This guide in particular is going to focus on how to get started using Mapbox GL JS with React. This JavaScript library will allow us to add beautiful and highly interactive maps to any React application with a minimal amount of code.

Application Setup

For ease of use, we are going to use create-react-app to get our application up and running. If you would like to follow along, you can find this guide in my sandbox repo.

Mapbox requires that you have an account to use Mapbox GL JS. If you do not have an account, head on over to their signup page. After creating your account, login and navigate to your account page at https://account.mapbox.com/. You should see a section titled "Access Tokens" as well as a "Default public token". In the root of the project, create a new .env file and copy your access token that you just tracked down. You will want to add this token to the .env file. It is generally best practice to store sensitive information like access tokens in a .env file and keep them out of version control.

# .env
REACT_APP_MAPBOX_TOKEN=<YOUR_TOKEN_HERE>

Next, we need to add Mapbox GL JS to our project as a dependency.

# yarn
yarn add mapbox-gl

# npm
npm install mapbox-gl

Creating the Map

With the basic application infrastructure setup and dependencies installed, we can create our fullscreen interactive map. If you are just looking to grab a snippet and go on your way, the below code block is your ticket. Otherwise, I will be walking through they key concepts block by block below.

import React, { useRef, useEffect } from "react";
import mapboxgl from "mapbox-gl";
// import the mapbox styles
// alternatively can use a link tag in the head of public/index.html
// see https://docs.mapbox.com/mapbox-gl-js/api/
import "mapbox-gl/dist/mapbox-gl.css";

// Grab the access token from your Mapbox account
// I typically like to store sensitive things like this
// in a .env file
mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_TOKEN;

const App = () => {
  const mapContainer = useRef();

  // this is where all of our map logic is going to live
  // adding the empty dependency array ensures that the map
  // is only rendered once
  useEffect(() => {
    // create the map and configure it
    // check out the API reference for more options
    // https://docs.mapbox.com/mapbox-gl-js/api/map/
    const map = new mapboxgl.Map({
      container: mapContainer.current,
      style: "mapbox://styles/mapbox/streets-v11",
      center: [-87.903982, 43.020403],
      zoom: 12,
    });

    // cleanup function to remove map on unmount
    return () => map.remove();
  }, []);

  return <div ref={mapContainer} style={{ width: "100%", height: "100vh" }} />;
};

export default App;

Alright, let's step through the above snippet line by line starting with the access token bit. Mapbox requires you to have an access token to use their Mapbox GL JS library. We already grabbed an access token in the application setup step and stored it in a .env file. We can now reference that variable in our application.

// Grab the access token from your Mapbox account
// I typically like to store sensitive things like this
// in a .env file
mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_TOKEN

We start by creating a reference for the map container using the [useRef](https://reactjs.org/docs/hooks-reference.html#useref) hook. We will use this ref to tell Mapbox where to render the map. Where the meat and potatoes of our map logic lives though is inside of the [useEffect](https://reactjs.org/docs/hooks-reference.html#useeffect) hook. Placing the logic within the useEffect hook ensures that the map does not render until the component has mounted and passing an empty dependency array to the hook ensures that the map is only rendered once.

The actual logic required to initialize the map is minuscule. Six lines of code to create a beautiful and interactive map! All we need to do is create a new variable called map and set its value to a new instance of a Mapbox GL JS map. The constructor can take a whole slew of configuration options (many of these will be covered in later posts), but we will be keeping it simple for this example. The only required options are container and style. You can find great descriptions of these two options + all the other available options in the Mapbox Docs. I added in the optional center and zoom options to render a nice map of Milwaukee.

We will want to add a cleanup function to the useEffect hook to ensure that our map is removed when the component unmounts. Lastly, we pass our ref to the div that is returned from our component and assign styles to ensure that the map takes up the full viewport width and height. That is it! If you start the application you should now have a fully interactive full screen map of Milwaukee that you can zoom and pan around.

const App = () => {
  const mapContainer = useRef();

  // this is where all of our map logic is going to live
  // adding the empty dependency array ensures that the map
  // is only created once
  useEffect(() => {
    // create the map and configure it
    // check out the API reference for more options
    // https://docs.mapbox.com/mapbox-gl-js/api/map/
    const map = new mapboxgl.Map({
      container: mapContainer.current,
      style: "mapbox://styles/mapbox/streets-v11",
      center: [-87.903982, 43.020403],
      zoom: 12,
    });

    // cleanup function to remove map on unmount
    return () => map.remove();
  }, []);

  return <div ref={mapContainer} style={{ width: "100%", height: "100vh" }} />;
};

export default App;

Next Steps

There are a whole slew of things we could do to improve the map that are beyond the scope of this first tutorial. The next post in this series will explore the myriad of predefined Mapbox Styles (aka basemaps) that are can be easily added to any map. The tutorial will provide useful context on each style and walk you through common use cases for each.

If you cannot wait until then, here is a list of some other predefined Mapbox Styles you could try out. Just swap out the existing style option for one of the following style urls.

  • mapbox://styles/mapbox/streets-v11
  • mapbox://styles/mapbox/outdoors-v11
  • mapbox://styles/mapbox/light-v10
  • mapbox://styles/mapbox/dark-v10
  • mapbox://styles/mapbox/satellite-v9
  • mapbox://styles/mapbox/satellite-streets-v11
  • mapbox://styles/mapbox/navigation-preview-day-v4
  • mapbox://styles/mapbox/navigation-preview-night-v4
  • mapbox://styles/mapbox/navigation-guidance-day-v4
  • mapbox://styles/mapbox/navigation-guidance-night-v4

If you found this post useful, please retweet, share, or pick up a copy of The Mapbox Developer's Handbook!