In my app's scenario, we made a render decision based on the input and output for the component render functions. Prior to rendering the view, if the data was identical to what already existed, no updates occurred. cljs made this cheap. After constructing the template (hiccup-style, more cljs data), if it wasn't different, we'd also skip the DOM update.
For methods on the component (handling various events and such), they all take a channel where they could send whatever events it was that they needed to send.
The data service managing a query for one or more components just blocked its goroutine until it received an update to its query data structure, resolved it, and if it was different than the existing query data structure, would debounce for more changes before sending off the request. Requests back to the server were ordered by an atomic counter (atom 0) such that out of order responses could be processed sanely. Everything was one-way.
Additionally, while we could dynamically render everything, pages were a layout data structure containing 0 or more components with associated data services. These were all described in EDN and thus could be serialized, queried, and rendered server side if necessary.
All of this machinery was pretty small, no more than about 1800 LOC building on top of some excellent cljs libraries.
https://www.packtpub.com/web-development/ext-js-application-...
One should also note that Seaside is likely the direct inspiration for Arc's (i.e. HN's) use of links that reference stored server-side closures by ID.
Edit: It looks like there is a new Pharo book that covers more advanced topics! http://deepintopharo.com/
Each component would render itself.
I personally think that this requires a lot of machinery under the hood, such as caching and batching requests (since no one knows ahead of time what components will need to be rendered).
At least that's what we built in our Qbix Platform (http://platform.qbix.com). Reusable components you just place on a page and they "just work". Unlike React, etc. they support more than just re-rendering. You can of course have a virtual DOM (via a lib like Mithril or https://github.com/Matt-Esch/virtual-dom etc.) but it would be nice to handle other kinds of events besides just "re-rendering".