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.
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>
);
};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>
</>
);
}
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>
);
};
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.
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;import { MapLayerMouseEvent, MapLayerTouchEvent } from "maplibre-gl";
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;
};