I have a nagging problem that keeps coming back to me though. The declarative state model is the holy grail for UI design, but if you try to mix in any form of imperative logic, it all falls apart. All of a sudden you need to understand and plug into poorly documented and opaque component lifecycle APIs in order to insert your imperative code and have it work correctly. And that really messes up the nice clean solution, making it look more like a chimera of two state models.
Some of that is fixed by libraries that create components native to your framework of choice, implementing the appropriate lifecycle hooks as necessary. But now you're relying on a library that adapts one library to another library, and now you've got a dependency sync problem on top of it all.
It wouldn't be such a problem if there weren't so many extremely useful libraries that depend on imperative code. Personally, I've run into massive problems trying to use D3, Leaflet, and Bootstrap, as well as a handful of others. I'm sure there are thousands more.
Not trying to take away from your point. When these declarative state models work well, it's a beautiful thing to behold. But there's always some point where the abstraction leaks.
https://svelte.dev/tutorial/onmount
https://reactjs.org/docs/state-and-lifecycle.html
https://blog.logrocket.com/introduction-to-vue-lifecycle-hoo...