Search code examples
reactjsreact-hooksarcgis-js-api

Value from useState is always initial value in map event callback


I'm using @esri/react-arcgis to display a basic map. The goal is to send a request on click to find some data for the clicked area.

This is my map:

<Map
    onLoad={handleMapLoad}
    onFail={handleMapLoadFail}
    onClick={handleMapClick}
    ... // bunch of other properties (basemap, styles etc)
></Map>

My problem is, that when onClick fires (and handleMapClick gets called), the values from the component's useState is always the initial value. It's defined like this: const [mapViewReference, setMapViewReference] = useState(null);.

It shouldn't always e null, because:

  1. The handleMapLoad gets called in the beginning. It sets the following state: setMapViewReference(view); whereas view is a property I directly get from the esri library.
  2. After that, I click on the map and the callback is executed
  3. If I call handleMapClick from a dummy button the state/value will be correct.

Is this something that could be handled by useCallback or a different hook? I'm not sure if this is a problem with the esri library...

This is right before my return (functional component):

const handleMapClick = async event => {
    console.log(mapViewReference); // This is always null, unless I call the function manually from a dummy button
    const point = mapViewReference.toMap(event);
    const response = await featureLayerReference.queryFeatures({...});
};

Solution

  • yes i used to have same issue with react-map-gl. i thing it's memo the onClick function when the component mount and doesn't update it when the map render on any state change. what i did is to fire a setState when map click event tigger and do all my actions in useEffect when the event state change:

    const [event,setEvent]= useState()
    
    useEffect(()=>{
    if(event){
       console.log(mapViewReference); // This is always null, unless I call the function 
         manually from a dummy button
        const point = mapViewReference.toMap(event);
        const response = await featureLayerReference.queryFeatures({...});
    }
    },[event])
    

    and for the Map component :

    <Map
        onLoad={handleMapLoad}
        onFail={handleMapLoadFail}
        onClick={setEvent}
        ... // bunch of other properties (basemap, styles etc)
    ></Map>