React functional component component unmount useEffect

304
9
Jump to solution
03-20-2025 10:33 AM
wadsonmakari
Occasional Contributor

Hi all,

I have developed a custom functional component by extending the EXB 1.16. My widget allows the user to interactively apply a definition query on one of the map layers. I would like the restore the map layer to its original state when the use closes the widget. 

I thought I would be able to use the useEffect hook as follows

useEffect(() => {

console.log('component setup')

//any widget initialisation code

return () => {

console.log('component clean up')

//restore layer to its original state when user closes widget

}

},[])

where component clean up code runs when the widget/component is closed by the user. It looks like the return function is not being called when I close the widget. 

Is there another way I can achieve this using react functional components?

Regards,

0 Kudos
1 Solution

Accepted Solutions
JeffreyThompson2
MVP Frequent Contributor

Use a useEffect function without a return statement. 

useEffect(() => {
  yourCode()
}, [props.state])
GIS Developer
City of Arlington, Texas

View solution in original post

9 Replies
DavidSolari
MVP Regular Contributor

ExB widgets aren't unmounted when you close the widget, they're just hidden. This is normally where I would say how to get that state but the API reference makes it incredibly difficult. You might be able to crawl through this example widget to find an answer, although I think this is more concerned with checking other widgets' states through the redux store.

wadsonmakari
Occasional Contributor

Thanks for your response. I am not looking to control the state of other widgets but to just run a function that will restore the layer that the user was interacting with to its original state when the user closes/hides the widget. 

Is there a onHide event or something like that?

 

Can someone from ESRI comment on this?

0 Kudos
JeffreyThompson2
MVP Frequent Contributor

https://developers.arcgis.com/experience-builder/api-reference/jimu-core/WidgetState/

There is a prop built into the base widget class you should be able that will show you if the Widget is open or closed. If I remember correctly it's just props.state. (terrible name for something in React)

GIS Developer
City of Arlington, Texas
DavidSolari
MVP Regular Contributor

Ah, found it, it's props.state which is a member of the WidgetState enum.

To illustrate what a mess finding this was: functional/pure widgets have no state beyond what you define, what's yoinked from a data store, or what's passed down through the props. All standard widgets take an AllWidgetProps object, which is the sum of WidgetProps and WidgetInjectedProps<T> (where T is the config object?). Buried in the injected props is the RuntimeInfo object which is where the state is stored, presumably because all of this info is coordinated by ExB and drilled into the widgets to keep a nice state tree. So yeah, easy, all you have to do is keep half of the jimu-core types in your head and you can find anything!

0 Kudos
JeffreyThompson2
MVP Frequent Contributor

The best Experience Builder documentation is IntelliSense. Type props. and see if any of the suggestions seem useful.

GIS Developer
City of Arlington, Texas
wadsonmakari
Occasional Contributor

Thanks both for your comments where do I check the props.state from? In the useEffect example above the return function is not called when the widget is closed/onhide.

 

0 Kudos
DavidSolari
MVP Regular Contributor

Unless something's gone sideways, closing the widget should trigger a re-render, which passes the updated state into the widget. Try adding an effect that has props.state as a dependency and it should only fire when that changes. If you need to explicitly look for a change instead of blind-firing on a certain state you can try something like this SO post.

0 Kudos
JeffreyThompson2
MVP Frequent Contributor

Use a useEffect function without a return statement. 

useEffect(() => {
  yourCode()
}, [props.state])
GIS Developer
City of Arlington, Texas
TimWestern
MVP

I know this got marked as a solution, but another option would be to take a snapshot of state before applying any of those changes, and perhaps catch the widget closing (perhaps a button to restore the layer view) that returns it to the previous state?

0 Kudos