This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-19
Channels
- # announcements (3)
- # asami (3)
- # babashka (39)
- # beginners (65)
- # calva (13)
- # cider (4)
- # clj-kondo (69)
- # cljdoc (19)
- # cljs-dev (2)
- # clojure (90)
- # clojure-dev (10)
- # clojure-europe (61)
- # clojure-france (15)
- # clojure-nl (8)
- # clojure-uk (2)
- # clojurescript (28)
- # conjure (2)
- # core-logic (4)
- # cursive (8)
- # datalevin (5)
- # datascript (7)
- # datomic (14)
- # depstar (4)
- # events (1)
- # graphql (7)
- # holy-lambda (5)
- # jobs (5)
- # kaocha (1)
- # malli (14)
- # membrane-term (13)
- # missionary (13)
- # nextjournal (6)
- # off-topic (1)
- # polylith (15)
- # portal (10)
- # re-frame (35)
- # reitit (1)
- # remote-jobs (3)
- # schema (3)
- # sci (121)
- # spacemacs (6)
- # tools-build (8)
- # tools-deps (74)
- # xtdb (7)
Is there any benifit using reg-sub-raw
over reg-sub
with input-fn + computation-fn when the computation-fn has to be reactive?
The main use-case for reg-sub-raw
is when you don't need db
. reg-sub
is just a wrapper that sets up the input functions (one of which provices app-db) and derefs their results for you.
I see, then it's what I'll use.
@p-himik Wouldn't any reg-sub
alternative to this be fired more often (from unrelated db changes), and generate more garbage?
(rf/reg-sub-raw
::mouse-coords
(fn [app-db _]
(let [x-pos (ra/cursor app-db [::x-pos])
y-pos (ra/cursor app-db [::y-pos])]
(ra/reaction {:x @x-pos :y @y-pos}))))
Seems like passing them in via signal subs would just shuffle the problem around to other parts of the code, not remove it.
I don't get what you mean. There will be no extra work done, of any kind. So what is the problem you're talking about?
The the extra reg-subs you are talking about would have their function get called anytime any part of the app-db changes, right? So that would be code not necessarily executed in my example above.
> would have their function get called anytime any part of the app-db changes, right?
Yes. And your cursor
internals will be re-evaluated just as well - to figure out whether the relevant value has changed. There's no magic, the app-db
will be wrapped in deref
.
The relevant part of the cursor
implementation:
IDeref
(-deref [this]
(let [oldstate state
newstate (if-some [r reaction]
(-deref r)
(let [f (if (satisfies? IDeref ratom)
#(get-in @ratom path)
#(ratom path))]
(cached-reaction f ratom path this nil)))]
(._set-state this oldstate newstate)
newstate))
Note that #(get-in @ratom path)
- that ratom
is app-db
in your case.Yea I understand that, but do you see how version 2 below would be doing more work?
(rf/reg-sub-raw
:mouse-coords-1
(fn [app-db _]
(let [x-pos (ra/cursor app-db [::x-pos])
y-pos (ra/cursor app-db [::y-pos])]
(ra/reaction {:x @x-pos :y @y-pos}))))
(rf/reg-sub
:mouse-coords-2
(fn [db _]
{:x (::x-pos db) :y (::y-pos db)}))
Your version 2 is broken because db
is a ratom there. Also, that is absolutely not what I was suggesting.
As long as that subscription is active, the hashmap would need to be created for every app-db change. That is not the case with version 1.
I'll quote myself, with extra emphasis: > If you have those coordinates served via signal subs then no.
Yea, and that is still false:
(rf/reg-sub
::x-pos
(fn [db _]
(js/console.log "Code #1 executed every time app-db changes")
(::x-pos db)))
(rf/reg-sub
::y-pos
(fn [db _]
(js/console.log "Code #2 executed every time app-db changes")
(::x-pos db)))
(rf/reg-sub
:mouse-coords-2
:<- [::x-pos]
:<- [::y-pos]
(fn [x-pos y-pos _]
{:x x-pos :y y-pos}))
In your code, ::x-pos
is executed exactly as often as the implementation of (ra/cursor app-db [::x-pos])
, with pretty much exactly the same cost. Same for ::y-pos
.
And your :mouse-coords-2
is broken because the first argument to the handler will be a vector with the values.
I still don't see what you mean.
If you don't believe me, just experiment. If you somehow manage to prove me incorrect, please share the code.
I'm pointing them out to not confuse the readers. I believe I haven't missed any points you made. The signal subs above will be evaluates just as often as your cursors. As a consequence of that, the resulting sub will be evaluated just as often as well.
I don't think I can convince you here, but just wanted to point out to the person asking the question that what you are proposing has some caveats
In both approaches, there's exactly the same amount of reactions, exactly the same topography. Even caching is there in both cases - in one case it's Reagent's cursor cache, in the other it's re-frame's subscription cache.
There are no caveats, except for the need to create extra 2 subs. Which can be a benefit by itself, if you use them elsewhere.
So the caveat is if you go the reg-sub route, you need to be careful about what you do in the function. That isn't the case with the cursors, because your function/reaction won't even be executed if the paths have not changed.
> you need to be careful about what you do in the function In which function exactly? With signal subs, you have 3 of them.
That statement is false. Only the signal subs handler will be re-evaluted. The sub that uses the signals and doesn't use the db will not be evaluated if the values returned by the signal subs are unchanged. That has nothing to do with re-frame. That's just how Reagent and its reactions work.
> In all that will get executed on every app-db change
The :mouse-coords-2
sub handler will not be executed on every app-db change.
Right. You said in which function exactly? And I said (in code) (filter gets-executed-on-every-app-db-change? functions)
It should be clear from the console.logging I added, no? Notice how the one you are objecting to does not have that logging, unlike the other 2.
I see what you mean. But you never indicated that you understand why your initial claim is incorrect, so I was still discussing the issue from that perspective.
You haven't shown any of my claims to be incorrect, just wrong syntax in some of the examples. Anyway I need to get back to work, so I'll have to leave it there.