RLayer

This component wraps a MapLibre Layer object. He manages its life cycle and is responsible for adding/removing it to the map. For this reason this component must be a descendant of RMap.

The id and the type props are readonly. This allows us to manage reactivity on the same instance throughout its lifecycle. In some cases you'll have to add a key prop to maintain this state. see below Error: RLayer id should not change.

Usage

import { RMap, RSource, RLayer } from "maplibre-react-components";
 
const townPaintStyle = {
  "fill-outline-color": "rgba(0,0,0,0.1)",
  "fill-color": "rgba(255,0,0,0.3)",
};
 
export default function App() {
  return (
    <RMap>
      <RSource id="thyez" type="geojson" data="/data/thyez.geojson" />
      <RLayer
        source="thyez"
        id="thyez-fill"
        type="fill"
        paint={townPaintStyle}
      />
    </RMap>
  );
};

Reactivity

Some props are reactives. Here is the complete list, it applies depending on whether or not the layer has this prop in its options.

type LayerReactiveOptions = {
  layout?: any;
  paint?: any;
  filter?: FilterSpecification;
  minzoom?: number;
  maxzoom?: number;
  beforeId?: string;
}
 

Be careful to define stable objects for layout, paint and filter props to avoid multiplying renderings.

import { RLayer, RMap, RSource } from "maplibre-react-components";
import { useMemo, useState } from "react";
 
const center = { lng: 6.53, lat: 46.09 };
 
export default function App() {
  const [red, setRed] = useState(false);
 
  const townPaintStyle = useMemo(
    () => ({
      "fill-outline-color": "rgba(0,0,0,0.1)",
      "fill-color": red ? "rgba(255,0,0,0.3)" : "rgba(0,0,0,0.3)",
    }),
    [red],
  );
 
  return (
    <>
      <RMap
        minZoom={12}
        initialCenter={center}
        mapStyle="https://openmaptiles.geo.data.gouv.fr/styles/osm-bright/style.json"
      >
        <RSource id="thyez" type="geojson" data="/data/thyez.geojson" />
        <RLayer
          source="thyez"
          id="thyez-fill"
          type="fill"
          paint={townPaintStyle}
        />
      </RMap>
      <div className="absolute right-4 top-4">
        <button onClick={() => setRed((r) => !r)}>
          {red ? "set Gray" : "set Red"}
        </button>
      </div>
    </>
  );
}
 

Map layer events

With MapLibre we can listen to map events associated to specific layer. See MapLibre doc reference MapLayerEventType.

// Initialize the map
let map = new Map({ /* map options */ });
 
// Set an event listener for a specific layer
map.on('the-event-name', 'poi-label', (e) => {
  console.log('An event has occurred on a visible portion of the poi-label layer');
});
 

With MapLibre React Components, you define these listeners directly as props of your <RLayer />.

import { MapLayerMouseEvent } from "maplibre-gl";
import { RMap, RLayer } from "maplibre-react-components";
 
export default function App() {
 
  function handleClick(e: MapLayerMouseEvent) {
    // your logic
  }
 
  return (
    <RMap>
      <RLayer
        onClick={handleClick}
        source="thyez"
        id="thyez-fill"
        type="fill"
      />
    </RMap>
  );
};
 

Error: RLayer id should not change.

When you have conditional renderers within your RMap component you will need to set the prop key for your RLayer to help React maintain its association with the correct component.

Consider id prop for MapLibre mapping and key prop for React mapping. If you want to know why see Tips: key vs id.

Reference

RLayer accept same props as Layer options plus beforeId. Check the MapLibre Layers reference page for details.

import { CustomLayerInterface, LayerSpecification } from "maplibre-gl";
 
type RLayerProps = LayerOptions & LayerCallbacks & {
  beforeId?: string;
};
 
type LayerOptions = LayerSpecification | CustomLayerInterface;
export type LayerCallbacks = {
  onMouseDown?: (e: MapLayerMouseEvent) => void;
  onMouseUp?: (e: MapLayerMouseEvent) => void;
  onMouseOver?: (e: MapLayerMouseEvent) => void;
  onMouseOut?: (e: MapLayerMouseEvent) => void;
  onMouseMove?: (e: MapLayerMouseEvent) => void;
  onMouseEnter?: (e: MapLayerMouseEvent) => void;
  onMouseLeave?: (e: MapLayerMouseEvent) => void;
  onClick?: (e: MapLayerMouseEvent) => void;
  onDblClick?: (e: MapLayerMouseEvent) => void;
  onContextMenu?: (e: MapLayerMouseEvent) => void;
  onTouchStart?: (e: MapLayerTouchEvent) => void;
  onTouchEnd?: (e: MapLayerTouchEvent) => void;
  onTouchCancel?: (e: MapLayerTouchEvent) => void;
  onTouchMove?: (e: MapLayerTouchEvent) => void;
};