Solved it, used useState instead of useRef, and it solved it.
const [map, setMap] = useState(null);
useEffect(() => {
if (dss_rowData && map) {
map?.setCenter({
lat: Number(laty),
lng: Number(longx),
});
}
}, [rowData, map]);
ref={(ref) => setMap(ref)}
Answer from emekaokoli on Stack Exchangemapbox gl js - how to make Map ref object available on first modal window render/launch - Geographic Information Systems Stack Exchange
uber/react-map-gl getMap & exposed Mapbox API - Stack Overflow
reactjs - How to force react-map-gl Map to rerender on props change - Stack Overflow
reactjs - Make Map ref object available on first modal window render/launch - Stack Overflow
Solved it, used useState instead of useRef, and it solved it.
const [map, setMap] = useState(null);
useEffect(() => {
if (dss_rowData && map) {
map?.setCenter({
lat: Number(laty),
lng: Number(longx),
});
}
}, [rowData, map]);
ref={(ref) => setMap(ref)}
...just as a little extra clarification for anyone else having the same issue:
<Map
ref={(ref) => setMap(ref)}
// ... other Map props ...
>
» npm install react-map-gl
I never did figure out why the re-render wasn't being triggered properly by the useEffect() call as we would expect it to. However, I figured out a workaround for those interested.
in the MapboxMap component, I added this:
const mapRef = useRef(null);
useEffect(() => {
if (mapRef?.current) {
mapRef.current.zoomTo(mapRef.current.getZoom());
}
}, [props.displayUploadedFiles]);
It goes into the underlying mapbox-gl map object and, whenever more files are updated, it "zooms in" to the current zoom level. This has the effect of if I were to pan the map manually, but automates it. It forces the map to re-render and makes it so the user can't perceive the viewport change.
you can use the useEffect to watch for changes in the prop and trigger the update of the map layers. You can also use the useMemo hook to memoize the geoJsons array, for performance.
import React, { useState, useEffect, useMemo } from 'react';
import { Map, Source, Layer } from 'react-map-gl';
function MapboxMap(props) {
const geoJsons = useMemo(() => (
props.displayUploadedFiles.map((file) => {
const id = JSON.stringify(file.features);
return (
<Source key={id} type="geojson" data={file}>
<Layer key={id} {...pointLayer} />
</Source>
);
})
), [props.displayUploadedFiles]);
// Use useEffect to trigger the map update when props change
useEffect(() => {
// Force a map update when the displayUploadedFiles prop changes
// This will re-render the map layers immediately
// You may also need to handle map updates here if required
}, [props.displayUploadedFiles]);
return (
<Map mapboxAccessToken={mapboxToken} ...>
{geoJsons}
{/* ... */}
</Map>
);
}
export default MyMap;
this should now update immediately when the displayUploadedFiles prop changes, without the need to pan the map.