A tour of how the Widget (Virtual DOM) code in Discourse works

@eviltrout I may be missing something here, but it seems that it’s not possible for a widget to retain a state if it’s re-attached as part of a re-render.?

In other words, if you have a series of nested widgets (i.e. widgets attached to widgets), whenever one of the widgets triggers a re-render, the whole chain is re-rendered and any state in the child widgets is lost as they are newly re-attached. Is that correct?

For example when widgetizing Babble, I tried to set a default view state for the menu widget and then toggle it when the menu was toggled between a single chat stream and the list of chat streams, but found that the state would always remain at its defaultState. I surmised that the state was being reset when the menu widget was re-attached on a re-render.

I then tried to stop the ‘propagation’ of the re-render trigger, but wasn’t able to. I ended up using widget actions to send an updated state to the ultimate parent widget (i.e. the header) and retained the state in the header. See here.

If my assumptions are correct, it would be useful to have a way to stop the propagation of the widget re-render trigger, or a way to ‘turn off’ the re-render triggers for certain widgets.

For example this would be useful for the search-term widget, which is currently triggering the entire header to be re-rendered on every keyup in the search input. It would also be useful in various ways for Babble.