Map Integration & React Wiring
This page describes how MapLibre GL JS is initialized and managed inside React, and how we handle style reloads and event lifecycles.
Initialization
useMap(mapContainer)loads libraries (loadMapLibraries) and callsinitializeMap(container)to create themaplibregl.Map.- On
load, we setmapLoaded/styleLoadedand runinitHarness(map)for debug helpers. - We debounce
style.loadto updatestyleLoadedafter style switches.
Key files:
src/hooks/useMap.jssrc/utils/mapUtils.js(library loading, Navigation/Scale controls, search control)
Style changes & basemap switching
- Basemap toggling is handled in
Sidebar/BasemapToggle.jsxandswitchBasemap()(inmapUtils). - Before switching, we dispatch
map:style:will-change(consumed byuseMapto pre-clearstyleLoaded). - After style reload,
style.loadreattaches handlers and rebinds draw layers where needed.
Centralized event lifecycle
- Use
useMapEvents(map, handlers, { reattachOnStyleLoad: true })to attach/detach map and layer events with automatic cleanup and re-attachment onstyle.load. - Prefer a single
useMapEventsinstance per module to avoid duplicated listeners.
Draw tools
useDrawTools(map, focusedArea)creates aMapboxDrawinstance, adds it to the map, and registersdraw.*events.- It initializes early and listens for
style.loadto rebind when styles change.
Best practices
- Keep React as owner of high-level state; use MapLibre sources/layers (
setData) for rendering. - For camera-synced overlays, avoid per-frame React state. Use
renderevents or a lightweightrenderTick. - Use a single persistent Popup, updated on
mousemovefor hover, to avoid flicker.