Managing mapbox-gl state in React app

Description of the problem

In the course of my work at geoalert.io, I have repeatedly encountered the problem of managing the state of an application in React with a built-in mapbox-gl

I plan to cover the topic in a series of articles, including this one:

The last two articles mentioned correspond to the 2 main problems I encountered while using mapbox-gl in React

  • Embedding mapbox-gl in React - storing the built-in mapbox-gl instance and making it accessible from other app components
  • Managing the state of a React app with mapbox-gl - since mapbox-gl has an internal state, you need to synchronize it with the state of the app itself

Embedding mapbox-glin React

There are several options for solving this problem, here are the most popular among them:

  • Using ready-made wrapper libraries
  • Self-native integration, for this option I would highlight 2 cases
    • Implementing as a React Component
    • Storing the map instance outside of React

Using ready-made wrapper libraries

The most popular among them

  • react-map-gl - is a solution from uber, perhaps the most sophisticated among others, one of the main drawbacks:
    • Steep learning curve, having sufficiently rich functionality, including for managing state, it is rather difficult to understand the library api
    • Has almost 1MB bundle size, which is quite a lot
  • react-mapbox-gl - ranks second in popularity, has an order of magnitude smaller bundle size and more concise and easy-to-understand api
  • @urbica/react-map-gl - the size of the bundle and api is about the same as react-mapbox-gl
  • use-mapbox-gl - I will use the opportunity to attach my solution, this is a lightweight React hook wrapping mapbox-gl

Self-service native integration

Implementing as a React Component

The main idea of this approach is to create a web map component, which must contain a DOM node for initializing the map, initialization logic, and it must also store an instance of the created map

The mapbox-gl documentation contains instructions on how to do this for a new React application.

Continuation and more detailed consideration of this issue, with various examples of implementation, wait in the next article

Storing the map instance outside of React

An example of such an implementation will also be considered in the next article

Managing state of React app with mapbox-glusing XState

As a rule, tutorials on using mapbox-gl in React end after the method of integrating the first into the second is described, articles about state management in such applications are rare, most articles on this topic are outdated at the moment

This article describes an example of state management with Redux using React class components

As mentioned above mapbox-gl has internal state for example properties such as

  • Map center coordinates
  • Zoom
  • Bearing
  • Current map style
  • Vector or raster user layers
  • etc.

Usually in the application interface, in addition to the map itself, there are elements whose display depends on the internal state of the map, for example, an element that displays the current coordinates and zoom, as in the above example

In addition to the state inside the map instance, the application can also have its own internal state, in our case, XState will be used for this

I'll cover this in more detail with an example of using XState in my next post

Useful links:

19