This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-06-30
Channels
- # announcements (40)
- # babashka (41)
- # beginners (32)
- # calva (15)
- # clara (8)
- # clj-kondo (14)
- # cljs-dev (30)
- # clojure (37)
- # clojure-dev (8)
- # clojure-europe (21)
- # clojure-norway (21)
- # clojure-uk (4)
- # clojured (3)
- # clojurescript (4)
- # community-development (10)
- # core-async (13)
- # cursive (23)
- # datomic (15)
- # emacs (9)
- # fulcro (3)
- # google-cloud (4)
- # graphql (24)
- # gratitude (2)
- # holy-lambda (4)
- # honeysql (5)
- # hyperfiddle (9)
- # keechma (1)
- # klipse (5)
- # lsp (23)
- # malli (4)
- # missionary (32)
- # pathom (28)
- # re-frame (2)
- # reagent (40)
- # reitit (17)
- # releases (2)
- # remote-jobs (1)
- # shadow-cljs (25)
- # specter (3)
- # vim (19)
- # xtdb (41)
First question is why the first identical?
gives true, and the second question is why the second identical
is false.
(let [a (r/render [app] (.getElementById js/document "app"))
b (r/render [app] (.getElementById js/document "app"))]
;; true
(identical? a b))
(let [a (r/render [#'app] (.getElementById js/document "app"))
b (r/render [#'app] (.getElementById js/document "app"))]
;; false
(identical? a b))
For the first case, I just tested
(identical? [app] [app])
gives false. Dunno how the (identical? r/render,,,) result is true.#'
in CLJS is a hack, it always returns a new cljs.core.Var
and as such is never identical?
given that CLJS doesn't usually have vars at runtime
so as far as reagent is concerned these are different vars (and as such different components)
> #'
in CLJS is a hack, it always returns a new cljs.core.Var
and as such is never identical?
given that CLJS doesn’t usually have vars at runtime
Yes. I just tried that out.
I wonder how the caching mechanism works. Given this code
(let [a (r/render [app] (.getElementById js/document "app"))
b (r/render [app] (.getElementById js/document "app"))]
;; true
(identical? a b))
It returnes the SAME component. Their must be some caching based on the value [app].pretty sure thats just what react-dom/render returns and it bind something to the dom #app
element and returns that if the mounted component was the same
But regarding reagent, when it sees [app], it should create some new instance right? And that instance happens to be equal (by value) to the already mounted instance?
no, this is all react. reagent basically just constructs a react element and tells react to render that
you can do
(let [x #'app
a (r/render [x] (.getElementById js/document "app"))
b (r/render [x] (.getElementById js/document "app"))]
;; true
(identical? a b))
Let me clarify my question, the input [app]
is fed into some reagent function first, and that result is then fed to react.
My question is, does reagent return the same instance? Given your response, it should, because react use (identical?) to test component equality.
Then given that, there must be some caching mechanism on reagent to achieve the purpose of returning the same instance.
and I answered that. all r/render
does is call (r/as-element [app])
and then (react-dom/render that-element some-extra-callback)
so no, reagent doesn't cache anything here. it is react that is doing that. but also not technically a cache. it just checks if it mounted something on the DOM #app
previously. if so it re-uses that and updates or replaces it.
I have not used reagent myself, but I spent a fair amount of time with react so this is all assuming it works similar to other react wrappers. fairly confident it all works like this but you should verify.
My intuition is that, since
(identical? (r/as-element [app])
(r/as-element [app]))
Is false. So react should return two different components, but instead it returns the same one. There must be something ongoing.This is my original question:
(let [a (r/render [app] (.getElementById js/document "app"))
b (r/render [app] (.getElementById js/document "app"))]
;; true
(identical? a b))
The r/render returns identical result.I mean basically just call (react-dom/render (r/as-element [app]) (.getElementById js/document "app") )
Ah. Is it because while the react element is different, the undelrying react component is the same (the app component) where as [app] is the element. React compares based on the component instead of elements.