Reputation:
I am learning react hooks
. In my code I have set the initial values for plotting map as
//map state
const [mapData, setMapData] = useState(
{ lat: 40.712776, lng: -74.0059, zoom: 5 }
);
In the useEffect()
call back I am loading the map once
useEffect(() => {
initMap();
}, []); // run once
Inside the initMap()
there is map.on()
method to get the updated geo locations. The initMap()
is
const initMap = () => {
mapboxgl.accessToken = 'token';
const map = new mapboxgl.Map({
container: mapContainer,
style: 'mapbox://styles/mapbox/streets-v11',
center: [mapData.lng, mapData.lat],
zoom: mapData.zoom
}); // load the map with init values
// update the `mapData` as map move
map.on('moveend', () => {
const { lng, lat } = map.getCenter(); // logs the updated lat and lon
setMapData({ lat: lat.toFixed(4), lng: lng.toFixed(4), zoom: map.getZoom().toFixed(2) }); // suppose to set the updated value
console.log(mapData); // not logging updated values!
});
}
The setMapData()
is not setting the state. But the map.on
is called and is logging the values.
Upvotes: 0
Views: 1186
Reputation: 21
This is also the case for useSelector. I don't believe React Hooks is being supported by Mapbox in this way. I have event handlers I add onto my map and those handlers cannot access the current values of the component's useState/useSelector. These values are always the values they were when the event handlers were added to the map. I have resorted to adding another state that triggers useEffects instead of handling it all in my event handler.
edit: It was brought to my attention that you can use redux's 'useStore' hook to grab the current redux store even in the Mapbox event handlers! It's tougher to test, however, bc you have to mock the 'useStore' manually. Hope that helps!
Upvotes: 2
Reputation: 8947
setState
is asynchronous, updated state may or may not be available to statements following it.
Use an effect hook that runs on a mapData update to react to changes.
useEffect(() => console.log(mapData), [mapData])
Upvotes: 1