If you are creating a Mapbox GL map using React, there may come a time when you want to be able to trigger Redux or other actions from within said popup. If you’re not using react-map-gl, this article is for you. If you’re looking for spoilers, see this codepen for a full implementation.

What sets this tutorial apart from others is that they use setHTML or they create a second React app inside the first one, which prevents you from using your usual set of tools for managing state from in the popup. This tutorial doesn’t. It allows you to manage and control state inside a Mapbox GL popup.

To make this happen, we need the following things:

  1. A component that holds the popup content that holds a reference
  2. A declaration of the component adjacent to the element that hosts the mapbox-gl map
  3. Something to put into the popup, and
  4. A trigger for the popup to occur

Step 1: Create the Popup Surround

The first step is to create a component called <PopupBase />. This is what’s going to surround the popup content.

import React, { useContext, useEffect, useRef } from "react";
import { mapContext } from "../context/mapContext";
import mapboxgl from "mapbox-gl";

const PopupBase = ({ children, lngLat, ...mapboxPopupProps }) => {
  const { map } = useContext(mapContext);
  const popupRef = useRef();

  useEffect(() => {
    const popup = new mapboxgl.Popup({})

    return popup.remove;
  }, [children, lngLat]);

  return (
    <div style={{ display: "none" }}>
      <div ref={popupRef}>{children}</div>

export default Popup;

Notice that we’re using “setDOMContent”. You want to use this method over the usual “setHTML”. With this, we’re going to place this by the map element.

Step 2: Put the Popup Surround Adjacent to the Map

Here, I use an active state value which holds a lnglat coordinate as a proxy for “should the popup be visible”. There are many ways to do this, and this may not be the best. But it works.

// Map.js - Mapbox GL Component

const [content, setContent] = useState(null);
const [popupLngLat, setPopupLngLat] = useState(null);

// ... (rest of the React component)

return (
      {popupLngLat && <PopupBase lngLat={popupLngLat}>{content}</PopupBase>}
      <div ref={(el) => (mapContainer.current = el)} style={styles} />

When the popupLngLat is set the first time, the PopupBase-component is triggered. In this example, we don’t have a function which removes the popupLngLat value when the popup closes. This still works, but it may make more sense to have actions that properly scrubs the state on close.

Steps 3,4: Add the Content in the Trigger

For this part, we have a component called PopupContent. In the codepen example, it’s just a set of react elements that have some arbitrary action. It can be whatever you choose it to be. Note that I build this content based on the array of features that is captured by the click event. Here, I set the content state hook to the content, as well as the lnglat of the popup. As shown before is sufficient to trigger the popup in the map.

        map.on("click", "geojson-layer", (e) => {

          const labels = e.features.map((feature) => (


That’s all there is to it. At this point, you will be able to do anything in a Mapbox popup you could do elsewhere in your React app.

Full Implementation

You can see a working example of this idea on Code Sandbox:

In here, I use context instead of redux to propagate change to the footer of the application based on actions a user takes in the popup. But it can be redux. It can be anything you decide is worth doing.

Talk to us

If you are having problems with mapping in JavaScript, or if you want to make your maps more engaging, Let us know. Sparkgeo spends a fair amount of time thinking about these problems, and can be of service. If you’re having trouble in the steps before making your maps (especially in the data-wrangling aspect), Sparkgeo also has your back. Let us help you make sense of this mirror world.

Sharing options
black and white checkered illustration

Tutorial • Darren Wiens

Using Mobile LiDAR to Create 3D Models

As a geospatial developer, a lot of what I do revolves around describing the physical world in a digital way. There are many ways to do this. Consider…

green grass field under blue sky during daytime

Tutorial • Gordon Logie

Sumas Lake Reborn: A Tale of Topography

The recent flooding in British Columbia is a harsh reminder that climate change is not a hypothetical scenario that lies somewhere in the future; its effects are being…

Tutorial • Chloe Papalazarou

Geospatial Technology for Flood Monitoring

Time-lapse of the November 14 atmospheric river event, acquired by the GOES-17 satellite On November 14, southern British Columbia experienced the devastating effects of an “atmospheric river” –…

Need a geospatial partner?

Our team complements organizations like yours—by providing on-tap access to geospatial, analytics, and mapping expertise.

Let’s talk

Join our team?

We’re always looking for skilled technologists to help us build the future of geospatial. Got a minute to find out more about us?

Working Here

Sharing options