This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-17
Channels
- # adventofcode (2)
- # beginners (153)
- # cider (14)
- # clara (9)
- # cljs-dev (8)
- # cljsjs (1)
- # cljsrn (4)
- # clojure (124)
- # clojure-dev (9)
- # clojure-france (18)
- # clojure-greece (22)
- # clojure-italy (11)
- # clojure-nlp (5)
- # clojure-russia (9)
- # clojure-spec (21)
- # clojure-uk (40)
- # clojurescript (82)
- # core-async (12)
- # cursive (3)
- # data-science (2)
- # datomic (225)
- # devcards (8)
- # docs (2)
- # duct (1)
- # emacs (18)
- # figwheel (2)
- # fulcro (117)
- # graphql (13)
- # hoplon (10)
- # jobs (7)
- # jobs-discuss (7)
- # keechma (8)
- # leiningen (4)
- # off-topic (16)
- # om (2)
- # om-next (3)
- # perun (11)
- # precept (4)
- # re-frame (24)
- # reagent (2)
- # remote-jobs (8)
- # ring (2)
- # ring-swagger (9)
- # rum (42)
- # shadow-cljs (8)
- # spacemacs (3)
- # specter (7)
- # uncomplicate (10)
- # unrepl (58)
- # yada (9)
how do people manage state with rum? I'm now mostly using a single global atom + rum/reactive + cursors, but this seems pretty much equivalent to reagent
@chrisblom Datascript is awesome
How do you let specific components update based when the db changes? With cursors its really easy to subscribe to a specific part of the app state, how do you do this with datascript?
@chrisblom You can't currently. I think right now you have to do a full re-render. I have a fork of datascript that I want to publish within a few months that allows exactly that (pretty similar to MobX if you know that, but fully normalized due to Datascript).
Yeah slightly similar, but much much simpler. You don't have to write any queries, it's all done automagically
You only deal with Entities (whcih are just like maps) and if you access some attribute, it gets recorded and triggers a re-render of the Component once this attribute changes.
cool, thats sounds nice, i like the ideas behind om-next (unified data model, subscribe by queries), but in practice i find writing parsers & reconciling etc too complex
Yeah I had the same problem. I actually started out with om-next but switched pretty soon. I'm pretty happy with the framework. I have this todo list which would properly implement a few other things, but maybe I'll just release it without implementing my todo-items. I have had this for over a year and really need to put it out there.
The idea is similar to the datascript+rum examples of tonsky. He specified when to re-render in the components.
@rauh @chrisblom What problems do you find just using cursors? Maybe I’m missing something about datascript (which I’ve never used) but it seems to me creating a cursor is sort of like expressing a subscription.
(A related question I’ve been meaning to investigate is whether you could just alter get-in to pay attention to the data path you specify. If it can do it with cursors, why not accesses?)
I don't like cursors. I have used it once in my code base and a few months later refactored it into callbacks.
for example, for a list element with a 'delete' button, I now need to pass a cursor the element, and a cursor to the list so i can do something like (swap! list-ref dissoc (:id @element-ref))
on click
IMO, and this is more general: I think state that is complex/nested isn't well expressed with maps + vectors. In general state is a graph. Ie. we absolutely need a graph database to stay sane. And that's why I use datascript which allows me to just walk the graph in any direction as I want to. By walking a graph you create a tree. Which is exactly what HTML is. So it's very natural.
That's also the entire idea of keeping your state completly normalized, which is preached by Redux folks + om-next. Which totally makes sens. But I don't want to do this by myself when there already is a DB (datascript) that keeps my complete state maximally normalized (E A V, datoms)
@lee.justin.m Instead of passing a cursor down, which is swap!
'd I just ask for a callback to be invoked when it wants to make changes to a state. Works well with up to 2-level deep but then it becomes awful.
Sometimes when I read about all of these tools and all of this terminology I feel like we overthink things and I wonder if I’m missing something so it is really good to hear your experiences.
FWIW, I don't write any queries in Datascript (I threw out the entire query engine). I only use Entities and I walk along them, just like a CLJS map. So the API is very much like maps/vectors but the db is just one long normalized index (EAV, plus the other indices)
I really liked mobx in javascript but I found that it was too easy to break it and totally impossible to debug. So then I went to redux, which is great, but has so much boilerplate that you need a type system to manage it. Now I’m here, having tried reagent, om, om-next… I like it so far.
Yeah I don't love MobX in general. If I were to do JS I would choose MobX state-tree probably. It got a lof of stuff right. It's the closes to a graph database. Unfortunatly not as flexible as Datascript however. No custom indices and you're constraint with your attributes.
I don’t think it’s ever going to be predictable until proxies make it into the browser
what’s awesome about clojurescript is that you already have a layer of indirection at the lowest level of data access. it’s like the language was built to solve all of these state management problems
Yeah I have a few answers for that. In my framework I can query a component in the REPL and it will exactly tell me what Datoms it uses to render. So it's pretty simple to understand.
while you guys are here: I just adapted react-dnd to rum. if you aren’t familiar, it uses decorator syntax, so you do something like export default DragDropContext(Backend)(MyApp)
to decorate your top-level component. I did this using a mixin to wrap the actual react component and return an altered state. This seems like it is working, but is there a better way of doing HOCs?
@justinlee i actually prefer cursors like 90% of the time, easy to understand and debug, its the 10% of more complex cases that i'm looking into
in my experience most of the time state is a tree, so cursors are fine in those cases
@chrisblom When the tree state of your app-db is ill-suited to your rendering needs, consider https://github.com/martinklepsch/derivatives