EsriTileLayer component for React Leaflet
React Leaflet is a React library that exposes Leaflet classes as React components, making it very easy to add interactive maps to React web apps.
This is the fifth in a series of posts on how I use the library. My intention is to share back some of the things I’ve learned and implemented in the hope of them being useful to others.
In this post, I present the EsriTileLayer
component which exposes Esri
tile layers by wrapping esri-leaflet as a React component.
First, the component:
import { createLayerComponent } from '@react-leaflet/core';
import * as L from 'leaflet';
import * as esri from 'esri-leaflet';
import PropTypes from 'prop-types';
const createEsriTileLayer = (props = {}, context) => {
const imagery = esri.tiledMapLayer({ url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer',
...props
});
const labels = esri.tiledMapLayer({ url: 'https://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer',
...props
});
const group = L.layerGroup([imagery, labels]);
return { instance: group, context };
};
const EsriTileLayer = createLayerComponent(createEsriTileLayer, () => null);
export default EsriTileLayer;
Things to note:
- Line 7: Satellite imagery tile layer
- Line 11: Place labels overlay tile layer
- Line 15: Both layers are combined into a single one
- Line 6, 9, 13: Any
props
passed to the component (e.g.token
) are forwarded to each tile layer
And here’s how you’d use it in a map:
import React from 'react';
import EsriTileLayer from './EsriTileLayer';
// import EsriTileLayer from './EsriTileLayerWrapper';
const GREECE_BOUNDS = [
[31.08, 14.26],
[44.91, 34.69],
];
function MyMap() {
return (
<MapContainer
bounds={GREECE_BOUNDS}
style={{ width: '100%', height: '100vh' }}
>
<EsriTileLayer />
</MapContainer>
);
}
export default MyMap;
Since esri-leaflet is supposed to be used in the browser and breaks with frameworks that perform SSR like Gatsby, I had to wrap it in the following component to make it work with gatsby build
:
import React, { useState, useEffect } from 'react';
const EsriTileLayerWrapper = (props) => {
const [Component, setComponent] = useState(null);
useEffect(() => {
import('./EsriTileLayer').then(mod => {
setComponent(() => mod.default);
});
}, []);
return Component ? <Component {...props} /> : null;
}
export default EsriTileLayerWrapper;
To use this component, you simply replace EsriTileLayer
with EsriTileLayerWrapper
.