Select to view content in your preferred language

in coordinates widget - how to use React "useState" correctly?

351
1
03-04-2024 07:38 AM
Labels (2)
MichaelLev
Regular Contributor

I develop on EXB 1.13 for 3D views.
I am newbie to React, and it seems that I don't know how to use "useState" correctly within the widget,
so even after values are "saved" by useState, they are null when reading them...

I'll describe what I did, the I'll present my problems:

I copied the original widget client\dist\widgets\arcgis\coordinates
into my custom widgets folder and I use it from there.
I modified that the display of x,y coordinates, zoom, scale etc. is updated "on the fly" as mouse moves.
But I noticed that if I modify mouse wheel alone, the display is not updated"on the fly", until I move the mouse horizontally or vertically.

In order that the display of zoom and scale will update "on the fly" as I change mouse wheel,
I did the next modifications:

1. after the useState
         const [currentJimuMapView, setCurrentJimuMapView] = useState(null)
     I added one more useState:
         const [lastMousePointAsScreenCoordinates, setLastMousePointAsScreenCoordinates] = useState(null)

2. In function "const onMouseMove", since  threeDPoint is object with x,y, I added:
     setLastMousePointAsScreenCoordinates(threeDPoint)

3. In function "const onActiveViewChange"
    I added next code:
    // When extent changes, update the display of x,y location, zoom, etc.
    reactiveUtils.watch(() => view?.extent, async () => {
        if (!view?.basemapView) return //since I use 3D sceneView
        if (lastMousePointAsScreenCoordinates) {
            const pointAsMapCoordinates = view.toMap(lastMousePointAsScreenCoordinates)
            await displayOnClient(pointAsMapCoordinates, lastMousePointAsScreenCoordinates)
        }
    })
})

4. Please note that function "const onActiveViewChange" does setCurrentJimuMapView(jimuMapView)
     yet, as I described in Problem_2, the saved value is being read as null...

my problems:

Problem_1. in (3), lastMousePointAsScreenCoordinates is null, though I saved it by useState...

Problem_2. Even if I bypass the useState and set some correct value in "pointAsMapCoordinates",
     still, at end of function "displayOnClient" there is the code:
     const view = currentJimuMapView?.view
     and here again a similar problem:
     Though currentJimuMapView has been set by useState in function "const onActiveViewChange",
      it is now null...

To summarize - I see I don't yet grasp how to save/read correctly by "useState" in the widget?

0 Kudos
1 Reply
RoderickPerendy
New Contributor III

Okay there are several things. 

First State updates are as asynchronous so they don't have immediately which from the looks of your code you want to happen. Instead try using useEffect method in combination with the useStates. 

Try something:
useEffect(() => { if (lastMousePointAsScreenCoordinates) { // Perform actions with the updated state } }, [lastMousePointAsScreenCoordinates]);

Do the samething thing with currentJimuMapView. 

the [] tells when UseEffect should fire, since the "state" isn't immediate it will change at the very end, then the effect kicks in and wola you should start seeing what you want to see. 
I generally use states for holding and setting states, but effects to make sure they fire. 

0 Kudos