Re-render a component from flyout using ReactDOM.render()

Usecase

React environment. I have a UI component (in the file Global.js) containing a function called “viewbase” exported as default

I need to re-render it from the code within a flyout submenu. How can I properly use ReactDOM.render() that I guess being the correct way to re-render the component ?

p.s. hope this question make sense…

Thanks in advance for your support

You can change key property of element that you want to force re-render.

Or if you want to re-render all then you can try location.reload().

Not quite sure I follow what you’re trying to do, but my first question is: why do you need to re-render? Forcing React to do a re-render is one of those typical “code smells”, which often implies that there’s probably a better mechanism.

I’d first start with making sure your component is properly encapsulated and has the correct state (and context if needed) available to it. Updating state or modifying the context of a component should cause it to re-render. If it doesn’t, my suspicion is that the component is unaware of something it should be.

Next, make sure you’re utilizing key appropriately. If your component is part of a larger group (where children are the same component types), React needs key to know which component to update. React is really good at pointing out when this is a problem, so check your console output.

It’s also worth looking at React Portals – your mention of the flyout here makes me think you might be getting close to a use case where portals might make sense.

Thanks @kerrishotts

why do you need to re-render?

—> I need to activate the restyling of the background of the buttons. when a Menu Item of the flyout is checked to evidentiate through the buttons background new color that we are in the new state choosed from the flyout Menu Item. In my code optionFlyerIsChecked is set according to a value retrieved by the component in the locaalstorage where has been previousli written by the code in the flyout (this mechanism substitute context that I cannot use in the flyout code)

let optionFlyerIsChecked = localStorage.getItem("AOptionChecked");

 <sp-action-button style= {(optionFlyerIsChecked === "true")  ? { backgroundColor: "violet" } : null } onClick= {() => clickHandler()} >

I’d first start with making sure your component is properly encapsulated and has the correct state (and context if needed) available to it. Updating state or modifying the context of a component should cause it to re-render. If it doesn’t, my suspicion is that the component is unaware of something it should be

→ even if iIm a real beginner on the subject I am pretty sure that everything is ok regarding my component’s state and context- It is my requirement that is a bit different and particular Example giving I thinlk that I cannot use the context from inside the flyout because flyout is not a component that can be wrapped inside context (correct ?)

Next, make sure you’re utilizing key appropriately. If your component is part of a larger group (where children are the same component types), React needs key to know which component to update. React is really good at pointing out when this is a problem, so check your console output.It’s also worth looking at React Portals – your mention of the flyout here makes me think you might be getting close to a use case where portals might make sens

→ I still don’t know how to use the key and react portal, I’ll study it !

anks @Jarda

You can change key property of element that you want to force re-render

→ I still don’t know how to use the key correctly, I’ll study it !

Or if you want to re-render all then you can try location.reload()

→ it works even if it doesn’t do exactly what I need (see my answer to Kerri) in fact it completely reloads the panel and rerenders everythigs from scratch while instead I just need to activate the restyling of the background of the buttons. when a Menu Item of the flyout is checked to evidentiate through the buttons background new color that we are in the new state choosed from the flyout Menu Item.In my code optionFlyerIsChecked is set according to a value retrieved by the component in the locaalstorage where has been previousli written by the code in the flyout (this mechanism substitute context that I cannot use in the flyout code)

let optionFlyerIsChecked = localStorage.getItem("AOptionChecked");

<sp-action-button style= {( optionFlyerIsChecked === "true")  ? { backgroundColor: "violet" } : null } onClick= {() => clickHandler()} >

.

Maybe I would have a context on a component where you change localStorage and when it’s changed, update that context. Then in your button component get context and use for switching background.

Check this example - I believe it’s exactly your use case. Although it’s for class based components, but it works pretty much the same for functionals.

I’m still learning React myself, but I think I would try this way. Someone will correct me if I’m wrong about such approach.

Thanks @Karmalakas

the problem, if I properly understood your kind reply, is that I believe I cannot use context in the code within the flyout (see my answre to Kerri) because flyout is not a component but is the code ruling the flyout menù behaviour. This is why I used localstorage as a work around to share information between the code in the flyout (setting the new state in localstorage) and the component where the button lives (getting the new state from local storage) This way works except that the component where the button lives is not immediately re-rendered when tte code in the flyout change the localstorage (would have if I could have used context instead of localstorage). I need a mechanism where the code in the flyout force the re-render of the component where the button lives immediately after that the code in the flyout set the new value in the localstorage. Forcing the complete reload of the plugin after setting the newstate in the localstorage works because during the reload the component where the button lives is rerendered (getting the new state from localstorage) but I don’t want to relaod the plugin (wich implicate many things ) I just need to force the rerender of the component where the button lives

Oh, right… My mistake :frowning: Until I read your both replies to the end I forgot it’s a flyout (outside of component)

thanks a lot anycase !!

If we would be talking about web-browser then you would be right. But UXP is not a browser. I had to use it myself by I can’t exactly remember why. I think it was due to <sp-dropdown> component or something nested in it or maybe another sp-element

When <element key="something1"> is changed. E.g. <element key="something2"> then everything nested is forced to re-render.

Do you think it works changing the key value of an element existing within a component from the code within the flyout that is not a component, as in my use case ?

If yes, should I use queryselector or whatelse in the code within the flyout to identify the target in the component to be changed (key = “mainButton” in the following example) ?

<sp-action-button key = "mainButton"  style= {( optionFlyerIsChecked === "true")  ? { backgroundColor: "violet" } : null } onClick= {() => clickHandler()} >

Thanks
Daniele

I personally use Redux Store to deal with these issues. So I can use dispatch() outside of any component. Store | Redux

Now that @Jarda mentioned dispatch(), I actually use it myself outside of components, but I use Easy-peasy lib for my plugins state management

1 Like

Great ! This means that I can call dispatch () from the code that is inside the flyout and, - even if it is not a component - this causes the immediate and automatic re-rendering of all the components that have subscribed to the store according to the state contained in the store ?

If you can kindly confirm that it works as I tryied to describe above, I think that it would be the proper solution !

Yes I think that is right. Anyway adding redux store and containers requires some learning process. If you never worked with it… it could take few days to understand it. But I use it in all of my UXP plugins and as could see in Alchemist it gives you enough flexibility to do some very nice things without big effort.

1 Like

It seems we have come up with a solution for this somewhat peculiar use case.

Tank you very much @Jarda @kerrishotts @Karmalakas for your contribution.

This forum is really precious and very effective !

Daniele

Noproblem I’m not afraid of the learning process because I have a very good companion helping me : the excellent book from @DavideBarranca which also deals with this specific theme and which ensures an extraordinarily fast and effective learning path !!

Daniele

As it was my first ever React project overall, I spent quite a bit of time looking into state management. Redux seemed so intimidating and then I found Easy-peasy. It was a really smooth sail TBH. Of course there were some bits to wrap my head around in general, but overall I believe it made my life much easier than I were to use Redux. I think Easy-peasy uses Redux under the hood and you can use Redux approach if needed something much more complex, but I found EP provided everything I needed

Just my 2 cents :slight_smile: