How to use Mapbox GL with React
Tags: react
Published: 2019-07-17 21:33:26

---
title: How to use Mapbox GL with React
published: true
tags: react
canonical_url: https://blog.logrocket.com/how-to-use-mapbox-gl/
---

![](https://thepracticaldev.s3.amazonaws.com/i/lrjddqf6zeoo4hc5qqlt.png)

## What is Mapbox?

[Mapbox](https://www.mapbox.com/) is a live location platform that allows developers to create interactive and intuitive map interfaces for a variety of applications. On the web, this is done using a JavaScript library called [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/api/) which uses [Web GL](https://get.webgl.org/) to render interactive maps from [vector lines](https://docs.mapbox.com/help/glossary/vector-tiles/) and [Mapbox Styles](https://docs.mapbox.com/mapbox-gl-js/style-spec/).

Are you looking to build map interfaces with React? Thanks to Uber engineers we can do this relatively easily through a package called [react-map-gl](https://uber.github.io/react-map-gl/#/) which provides React integration for mapbox-gl as well as an easy-to-use component library to build on.

In this article, we are going to make use of `react-map-gl` to build two map components, one that displays your current location and another that allows you to search for locations across the globe.

First, we’ll bootstrap our application with [create-react-app](https://github.com/facebook/create-react-app) by running `create-react-app mapbox-react`.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## Locating your position

We would like to start with pinpointing one’s location. With `react-map-gl` we can do just that using an in-built component called `GeolocateControl` which allows us to track the user’s location through the browser. Before we can do this, we have to initiate the map using the `MapGL` component from `react-map-gl`. Let’s look at how we do this in code and to make things interesting we’ll use React Hooks.

Let’s install react-map-gl by running `npm install react-map-gl`.

Now let’s set up our component.
```jsx
import React,{ useState } from 'react'
import MapGL, {GeolocateControl } from 'react-map-gl'
import config from '../config'
import 'mapbox-gl/dist/mapbox-gl.css'

const TOKEN=config.REACT_APP_TOKEN

const geolocateStyle = {
  float: 'left',
  margin: '50px',
  padding: '10px'
};

const Map = () => {

  const [viewport, setViewPort ] = useState({
    width: "100%",
    height: 900,
    latitude: 0,
    longitude: 0,
    zoom: 2
  })

  const _onViewportChange = viewport => setViewPort({...viewport, transitionDuration: 3000 })
  
  return (
    <div style={{ margin: '0 auto'}}>
      <h1 style={{textAlign: 'center', fontSize: '25px', fontWeight: 'bolder' }}>GeoLocator: Click To Find Your Location or click <a href="/search">here</a> to search for a location</h1>
      <MapGL
        {...viewport}
        mapboxApiAccessToken={TOKEN}
        mapStyle="mapbox://styles/mapbox/dark-v8"
        onViewportChange={_onViewportChange}
      >
        <GeolocateControl
          style={geolocateStyle}
          positionOptions={{enableHighAccuracy: true}}
          trackUserLocation={true}
        />
      </MapGL>
    </div>
  )
}

export default Map
```
The code shown above creates a map with the ability to pinpoint your current position by clicking on a button at the top left corner of the page. Let us breakdown how that works.

To initiate our map, we initiate our Map component and use the state Hook to initiate an object called `viewport` which we’ll feed to the MapGL component as props. We’ll use `viewport` to initiate the initial coordinates of the map along with its zoom and size.

We also initiate a `setViewport` function that will be used to update the values of the viewport. The `MapGL` component takes three more props, `mapboxApiAccessToken` which is the [access token](https://docs.mapbox.com/help/glossary/access-token/) required to make calls to the mapbox API and can be obtained from mapbox. `mapStyle` links to a variety of map styles provided by mapbox, in this case, we’ll use dark mode.

The last prop is `onViewportChange` which is a function that we use to update our `viewport`. That’s it, just like that we have a functional map! Now we need to add the location services.

To add geolocation, we import the `GeolocateControl` component which we’ll provide three props to. The first is some the styling declared as `geolocateStyle` earlier passed as a React style object, this determines the size and placement of the button that triggers the geolocation service. The next prop us `positionOptions` which is an object containing the options passed to the Geolocation API to get and watch the user’s position such as enabling high accuracy which we will do by setting `enableHighAccuracy` to true. We also set a prop called `trackUserLocation` to true, this makes the geolocate button a toggle that monitors and updates the user’s location when it changes.

## Searching for a location

To be able to search for a user’s location we shall build on the capabilities of `react-map-gl` using a package called [react-map-gl-geocoder](https://www.npmjs.com/package/react-map-gl-geocoder) which is a React wrapper for the mapbox-gl-geocoder for use with react-map-gl.

To install it, run `npm install react-map-gl-geocoder`

We’ll also be using [deck-gl](https://deck.gl/#/), a visualization framework from Uber, to add an overlay marking the area we have searched on our map for greater readability. To install it `run npm install deck.gl`.

Great, now we are ready to build our component, which we will name `SearchableMap`, our code should look like this:
```jsx
import "mapbox-gl/dist/mapbox-gl.css"
import "react-map-gl-geocoder/dist/mapbox-gl-geocoder.css"
import React, { Component } from 'react'
import MapGL from "react-map-gl";
import DeckGL, { GeoJsonLayer } from "deck.gl";
import Geocoder from "react-map-gl-geocoder";

const token = process.env.REACT_APP_TOKEN 

class SearchableMap extends Component {
  state = { 
    viewport :{
      latitude: 0,
      longitude: 0,
      zoom: 1
    },
    searchResultLayer: null
  }

  mapRef = React.createRef()

  handleViewportChange = viewport => {
    this.setState({
      viewport: { ...this.state.viewport, ...viewport }
    })
  }
  // if you are happy with Geocoder default settings, you can just use handleViewportChange directly
  handleGeocoderViewportChange = viewport => {
    const geocoderDefaultOverrides = { transitionDuration: 1000 };

    return this.handleViewportChange({
      ...viewport,
      ...geocoderDefaultOverrides
    });
  };

  handleOnResult = event => {
    this.setState({
      searchResultLayer: new GeoJsonLayer({
        id: "search-result",
        data: event.result.geometry,
        getFillColor: [255, 0, 0, 128],
        getRadius: 1000,
        pointRadiusMinPixels: 10,
        pointRadiusMaxPixels: 10
      })
    })
  }

    render(){
      const { viewport, searchResultLayer} = this.state
      return (
        <div style={{ height: '100vh'}}>
          <h1 style={{textAlign: 'center', fontSize: '25px', fontWeight: 'bolder' }}>Use the search bar to find a location or click <a href="/">here</a> to find your location</h1>
          <MapGL 
            ref={this.mapRef}
            {...viewport}
            mapStyle="mapbox://styles/mapbox/streets-v9"
            width="100%"
            height="90%"
            onViewportChange={this.handleViewportChange}
            mapboxApiAccessToken={token}
            >
              <Geocoder 
                mapRef={this.mapRef}
                onResult={this.handleOnResult}
                onViewportChange={this.handleGeocoderViewportChange}
                mapboxApiAccessToken={token}
                position='top-left'
              />
            </MapGL>
            <DeckGL {...viewport} layers={[searchResultLayer]} />
        </div>
      )
    }
}

export default SearchableMap;
```
First, we create a map container with the `MapGL` component, as we did in the previous component. Next, we use the Geocoder component from `react-map-gl-geocoder` which is a search component that returns the coordinates of a given location from the Mapbox API.

It takes a few props. The `onResult` prop is a function that is called when a result parameter is returned from the search and in our case, it creates a `GeoJsonLayer` object and places it in state as `searchResultLayer`. This GeoJsonLayer is then used to create a deck-gl layer over the map indicating the location searched for in the map.

Just like the `MapGL` component, the Geocoder also has an `onViewportChange` function that is called to update the map, in our case we’ve chosen to create a separate function to handle this called `handleGeocoderViewportChange` so as to override the transition duration when updating the viewport on the map. If you wish to use the defaults, you can use the same viewport change handler as MapGL. The geocoder also requires the mapbox token to access the mapbox API and fetch locations.

When searching, our geocoder will suggest some locations as shown below.  
 ![mapbox](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/07/mapboxapp.png?resize=427%2C512&ssl=1)

You will also notice we create and use a Ref that we use to integrate the two components, and it is passed to both components as a `mapRef` prop.

The last piece in our searchable map is the deck.gl layer we had created data for. This will render on the map when we search for an area. It is passed the viewport details as well as the `searchResultLayer` which it uses to generate the dot over our location as shown below.

![map display](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/07/mapdisplay.png?resize=512%2C294&ssl=1)

And that’s it, we have a searchable map!

## Routing

You will notice I placed links to the components at the top of each component. Now let us edit App.js to add routing to link these two components. We’ll be using `react-router-dom` to achieve this, run `npm install react-router-dom`. All set, let’s add our routes.
```jsx
import React from 'react'
import './App.css'
import Map from  './components/Map'
import SearchableMap from './components/SearchableMap';
import { Route, Switch, BrowserRouter } from 'react-router-dom'

function App() {
  return (
      <div>
        <BrowserRouter >
        <Switch>
            <Route exact path="/" component={Map} />
            <Route exact path="/search" component={SearchableMap} />
        </Switch>
        </BrowserRouter>
      </div>
  )
}
export default App
```
Great, we are all set up, run your app to play around with the two components. Here’s how they will look once complete.  
 ![geolocator](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/07/geolocator.png?resize=512%2C296&ssl=1)

![geolocator location](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/07/geolocatorlocation.png?resize=1600%2C781&ssl=1)

## Conclusion

Mapbox GL is a great tool for creating interactive map interfaces and with `react-map-gl` it’s even easier to integrate into React applications. In addition to this the surrounding ecosystem of packages from Uber, you can expand on its functionality to create a variety of great looking interfaces using deck-gl to create stunning looking overlays.

* * *

## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).

* * *

The post [How to use Mapbox GL with React](https://blog.logrocket.com/how-to-use-mapbox-gl/) appeared first on [LogRocket Blog](https://blog.logrocket.com).