I really like the "selector" pattern. Your app state should not have to reflect your UI component tree. Rather you use selectors to subscribe to some part(s) of your application state and derive any necessary values in the subscription/selector function.
Representing your app state as a single source of truth and expressing all changes to state as effect handling functions means you can now easily test your front-end app without involving a dom at all! It is state transitions that are interesting.
Of course there are other options like Redux and Vuex for React and Vue respectively as well as the elm language if you want to go all in on static types and compile time error checking.