This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-14
Channels
- # aleph (3)
- # announcements (16)
- # aws (6)
- # babashka (10)
- # beginners (28)
- # cider (1)
- # clj-kondo (14)
- # cljdoc (2)
- # cljs-dev (27)
- # cljsrn (7)
- # clojure (78)
- # clojure-europe (2)
- # clojurescript (14)
- # conjure (6)
- # core-async (2)
- # fulcro (5)
- # helix (7)
- # jobs (1)
- # lgbtq (1)
- # malli (12)
- # missionary (1)
- # nbb (10)
- # pathom (1)
- # portal (12)
- # protojure (1)
- # re-frame (41)
- # react (2)
- # reitit (1)
- # reveal (1)
- # shadow-cljs (72)
- # sql (11)
- # tools-deps (8)
- # vim (1)
- # xtdb (4)
Noob quesiton, why use rf/dispatch to call functions? Why not directly invoke some functions?
I assume you mean something like a not built-in :call-fn
effect and not "why use dispatch
at all".
To simplify views, make their interaction with the outside world more precise (one way to get the data, one way to change it), instrument such calls.
I was referring to the (rf/dispatch [:some-event ]). Why not diretctly call (some-event-func)
Only thing I can come up is the pub/sub functionality. But is there really such a need?
I can't come up with succinct answer to that. I would suggest reading through the documentation at https://day8.github.io/re-frame/re-frame/ Namely, the main page and the "The Basics" and "Mental Model Omnibus" sections on the left. All while keeping in mind the question: "Would just calling a regular function allow me to do that?"
When you call dispatch, the event is placed in the queue instead of immediately being run - helps with the async singlethreaded nature of js. Far less likely to do bad things in the middle of a render cycle
Do you need to do them for a small application? Nah, use functions and swap out an app-state
atom
The http-xhrio library is a fantastic example - you trigger a page load, maybe save something to the db to display something for the user, and also do another fx for tracking
These aren’t things that are useful in a small codebase, but it’s a lot easier to keep things separated as you head for that 20KLOC+ codebase
So it seems to me: 1. Async unblocks user actions 2. Decoupling invocation and implementation (good in itself, but using keyword :event-names makes it hard to find the handler, and also hard to refactor had we change the :event-name) 3. pub/sub benefit
Although if you use namespaced event names it makes it very easy to find where things are coming from, usually
I'd say the third one is the main one, even though it is rather ambiguous. Async is easy to handle, as I mentioned. Decoupling is mostly superficial with events - you still have to use the right event name, the right arguments, and call that event at the right time (if the event handler depends on time).
And by default, re-frame queue is only internally async - if you have a bazillion of events, the rendering, along with any user actions, will 100% be blocked. And there are ways around that.
How do you keep track of the event names? While there is a https://day8.github.io/re-frame/App-Structure/ that advises to put event handlers under a dedicated events.cljs file, but I’d prefer a more domain driven model, where I might put the event handlers under account.cljs, sync.cljs, bookmark.cljs, etc. This makes me hard to find out: what event names I’ve defined? Are the being imported on app load or not?
@U24QP2D4J Could you shed some lights on how 20K loc codebase organizes ?
So disclaimer before any of this: this is work done by someone self taught and may/not represent best practice
There’s a lot of usage of namespaced keywords - almost to the point of abuse sometimes
Each table/object has its own resolves.clj for backend resolving, then resolvers.cljs for fetching/storing
Since each fetch really has 2-3 events with it - the fetch itself, the success which marshalls the data into the db, and the failure event (but often the failure is the same event for many)
The mutations similarly have their own, mutations.clj for server side, and mutations.cljs for client side
I’ve seen some people that like to put all their events into a single file to keep them there, but frankly that gets too large too quickly for my taste
There’s another set of namespaces for dealing with app routing - which are also under the same top level keyword
Then other parts of your application which cross multiples of these do so through these singular events. There’s surprisingly few cases where we need to call a ;db
that needs to hit multiple top level keywords, but that’s generally solved by factoring out the functions and calling them across