react-map-gl

repository·master·Indexed 27 days ago

https://github.com/visgl/react-map-gl

A suite of React components providing a declarative API for interacting with MapLibre GL JS and Mapbox GL JS. It offers a reactive wrapper for map state management, including components like Map, Layer, Source, and various controls (AttributionControl, FullscreenControl, GeolocateControl), ensuring synchronization between map state and React props.

Tokens
33.9K
Snippets
63
Records
162
Agent score
92%

What's inside react-map-gl

  1. Overview of react-map-gl supported libraries

    master

    react-map-gl is a suite of React components designed to work with the following map libraries:

    • MapLibre GL JS: An open-source TypeScript library for publishing web maps.
    • Mapbox GL JS: A JavaScript library for interactive, customizable vector maps (requires a billable Mapbox token for Mapbox hosted basemaps).
    • Mapbox GL JS v1: The last free-open-source version of Mapbox GL JS. It can be used without a Mapbox token if you do not use Mapbox hosted basemaps.

    While it may be possible to use other compatible forks, they are not officially supported.

  2. Integrate other vis.gl libraries for advanced visualization

    master

    For high-performance or large-scale data visualization, consider integrating other libraries from the vis.gl ecosystem:

    • deck.gl: A WebGL-powered framework for visualizing large datasets.
    • loaders.gl: Specialized loaders for big data file formats (point clouds, 3D geometries, geospatial formats, etc.).
    • nebula.gl: 3D-enabled GeoJSON editing built on top of deck.gl and React.
  3. Access imperative Map methods via React ref or useMap hook

    master

    To call imperative Map methods (like those provided by MapLibre), you can use a React ref or the useMap hook. When using a ref, ensure you use the MapRef type to access the safe subset of methods that do not conflict with React props.

    Warning: Some native Map methods are intentionally hidden from the MapRef object to prevent state mismatches between React props and the underlying map state. For example, setStyle() is hidden because you should use the mapStyle prop instead. If you must access these hidden native methods, use getMap() to retrieve the underlying native instance.

    import * as React from 'react';
    import {useRef, useCallback} from 'react';
    import {Map} from 'react-map-gl/maplibre';
    import type {MapRef} from 'react-map-gl/maplibre';
    
    function App() {
      const mapRef = useRef<MapRef>();
    
      const onMapLoad = useCallback(() => {
        // mapRef.current provides access to safe Map methods
        mapRef.current?.on('move', () => {
          // do something
        });
      }, []);
    
      return <Map ref={mapRef} onLoad={onMapLoad} ... />;
    }
  4. Restore RTLTextPlugin in v8.0

    master

    In v8.0, the default RTLTextPlugin loaded from mapbox.com has been removed to align with MapLibre's default behavior. To restore previous behavior, you must manually specify the pluginUrl or provide your own plugin source via the RTLTextPlugin prop on the Map component.

    <Map RTLTextPlugin="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.3/mapbox-gl-rtl-text.js" />
  5. Provide a Mapbox Access Token to react-map-gl

    master

    If you are using mapbox-gl@>=2.0.0 or mapbox-gl@1.x with Mapbox data services, you must provide a Mapbox access token. You can provide the token using one of the following three methods:

    1. Prop: Pass the mapboxAccessToken prop directly to the map component.
    2. Environment Variable: Set the MapboxAccessToken environment variable. If you are using Create React App, use REACT_APP_MAPBOX_ACCESS_TOKEN.
    3. URL Parameter: Include the token in the URL, for example: ?access_token=TOKEN.

    It is recommended to use environment variables to minimize the risk of leaking your token.

  6. Upgrade to react-map-gl v3

    master

    Upgrading to v3 involves several breaking changes regarding component structure, overlay placement, and utility functions.

    Node Version Requirement

    When building react-map-gl, you must use Node >= v6.4.0. This requirement does not apply if you are using a prebuilt version of the library.

    Map Component Changes

    The Map component is now split into two components:

    1. StaticMap
    2. InteractiveMap (the default export, designed for compatibility with v2).

    Viewport Callback Changes

    The viewport parameter in the onChangeViewport callback now includes width and height. If your application manually composes width and height with the viewport object, you must ensure the component props are ordered so that your explicit dimensions override the values inside the viewport object.

    Overlay Changes

    • Relocation: Less frequently used overlays like DraggablePointsOverlay, ChoroplethOverlay, and ScatterplotOverlay have been moved to examples. If needed, copy their source files into your project.
    • Rendering: Overlays must now be rendered as children of the main react-map-gl component to ensure automatic synchronization with the map viewport.

    fitBounds Utility

    The fitBounds utility has moved to the math.gl library. You should now use WebMercatorViewport from viewport-mercator-project to handle bounds fitting.

    // v3 Viewport Prop Ordering
    // BAD: 'width' and 'height' below will be overridden by what's in the 'viewport' object
    <ReactMapGL width={500} height={400} {...viewport} />
    
    // GOOD: 'width' and 'height' below will override the values in 'viewport'
    <ReactMapGL {...viewport} width={500} height={400} />
  7. Upgrade to react-map-gl v1

    master

    When upgrading from v0.6.x to v1:

    Importing Overlays

    Overlay components (e.g., HTMLOverlay, CanvasOverlay, SVGOverlay) are now named exports from the main package. You no longer need to import them from relative source paths.

    Map State Management

    The state reported by onViewportChanged now contains additional transient fields. To ensure compatibility and future-proofing, it is recommended to save the entire mapState object in your application store and pass the complete object back to the component, rather than tracking individual fields like longitude, latitude, or zoom separately.

    // v1.0 (New way)
    import MapGL, {SVGOverlay} from 'react-map-gl';
    
    // v0.6 (Old way)
    import MapGL from 'react-map-gl';
    import SVGOverlay from 'react-map-gl/src/api-reference/svg-overlay';
  8. Install react-map-gl

    master

    To use react-map-gl, you must have react >= 16.3 installed. You can choose to use either maplibre-gl or mapbox-gl as the underlying engine.

    For MapLibre:

    npm install react-map-gl maplibre-gl

    For Mapbox:

    npm install react-map-gl mapbox-gl
    # Using Maplibre
    npm install react-map-gl maplibre-gl
    
    # Using Mapbox
    npm install react-map-gl mapbox-gl
  9. Optimize Map Performance with reuseMaps

    master

    By default, react-map-gl releases all internal resources when a Map component unmounts. If your application frequently mounts and unmounts maps (e.g., in tabs or collapsible UI), set reuseMaps={true}.

    This retains the underlying Map instance in memory so it can be reused when the component remounts, which can help avoid Mapbox's billable initialization events.

    Note: When reusing maps, only reactive props and initialViewState are respected, as some map options cannot be modified after initialization.

  10. Inject native Mapbox layers using Source and Layer components

    master

    To add custom data and native Mapbox layers to your map, use the Source and Layer components. The Source component defines the data (e.g., a GeoJSON FeatureCollection), and the Layer component defines how that data is styled using the Mapbox style specification. This approach works for both Mapbox and MapLibre implementations.

    import * as React from 'react';
    import Map, {Source, Layer} from 'react-map-gl/maplibre';
    import type {CircleLayer} from 'react-map-gl/maplibre';
    import type {FeatureCollection} from 'geojson';
    
    const geojson: FeatureCollection = {
      type: 'FeatureCollection',
      features: [
        {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [-122.4, 37.8]
          },
          properties: {title: '915 Front Street, San Francisco, California'}
        }
      ]
    };
    
    const layerStyle: CircleLayer = {
      id: 'point',
      type: 'circle',
      paint: {
        'circle-radius': 10,
        'circle-color': '#007cbf'
      }
    };
    
    function App() {
      return (
        <Map
          initialViewState={{
            longitude: -122.45,
            latitude: 37.78,
            zoom: 14
          }}>
          <Source id="my-data" type="geojson" data={geojson}>
            <Layer {...layerStyle} />
          </Source>
        </Map>
      );
    }