The LISP people were right to make trees essentially a first class data structure.
Using trees of these collections is quite customary in Clojure - on the front-end you might keep the application state in a single atom, like re-frame does and update various branches of it using events/ effects and listening on changes to those branches using subscriptions. This approach work for us at orgpad.com quite well.
a{ nested:tree with:{lots-of:data and:more}}
https://clojure.org/guides/learn/hashed_colls#_maps