This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-08-03
Channels
- # announcements (5)
- # babashka (7)
- # beginners (119)
- # biff (4)
- # cider (7)
- # clj-kondo (26)
- # cljfx (3)
- # cljs-dev (2)
- # clojure (28)
- # clojure-austin (18)
- # clojure-europe (9)
- # clojure-france (6)
- # clojure-norway (4)
- # clojure-uk (3)
- # clojurescript (6)
- # community-development (1)
- # core-async (4)
- # cursive (9)
- # data-science (12)
- # datomic (13)
- # duct (18)
- # emacs (15)
- # etaoin (5)
- # events (13)
- # honeysql (46)
- # hyperfiddle (9)
- # jackdaw (5)
- # jobs (13)
- # keechma (4)
- # lsp (37)
- # malli (32)
- # nbb (14)
- # off-topic (10)
- # other-languages (2)
- # polylith (4)
- # programming-beginners (3)
- # reagent (27)
- # reitit (1)
- # shadow-cljs (32)
- # sql (11)
- # tools-build (5)
- # tools-deps (3)
- # vim (14)
- # xtdb (11)
How can I have an input field with an onchange handle that has a debounce attached, but still has the value of the atom it's synchronized to? Basically if I use :value it doesn't let you change it at all, and if you use :default-value it doesn't change when the atom changes.
:default-value (:decltempl @mod) ; doesn't update the input when @mod changes
:value (:decltempl @mod) ; doesn't let me change the input
:on-change (cm/debounce #(swap! mod assoc :decltempl (.. % -target -value)))
(`(def debounce #(goog.functions/debounce % 1000))` )
Wrap :input
with your own component, have two ratoms within it that track the internal value and the external value. Update the internal one in the :on-change
and when the passed external value does not correspond to the stored external value on render. Call the debounced function in :on-change
as well.
You can see how re-com
does it in its input components.
You lost me on the external value corresponding render part
What is this re-com we're talking about?
But just the exact thing I'm not understanding is not clear to me from this code either... when is this external model compared? I just can't figure out where this is going with the deep nesting going on https://github.com/day8/re-com/blob/fcebaeefbe87c664222d50b69bdfc1b3faa05db8/src/re_com/input_text.cljs#L97-L99
It's a form-2 Reagent component. That comparison is done on every call to that component, which happens every time its properties change (with some exceptions that aren't of any importance here).
Ah so simplified version would be someting like
(defn outer [extern]
(let [ext (r/atom) int (r/atom)]
(defn [extern]
(when (not= @extern @ext)
(reset! ext @extern)
(reset! int @extern))
...
and then you debounce both the external states, and update the internal one directly?Only the inner defn
is actually fn
, right.
No, you debounce only the :on-change
you pass to the component. Don't debounce state comparison and resetting - just reuse what re-com has. Should work.
yea but on-change needs to update all 3 values right
interal for rendering, and debounced both external values, to make the change visible, and to be able to detect external changes
There are two :on-change
functions - one your component receives and one the wrapped :input
receives.
The former should be debounced, called from the latter, and it should change the external model.
The second :on-change
should call the first one and change the internal model.
Well, I'm just describing what should be going on based on my memory of the approach. The actual working source code of re-com should be a better reference than that, even if it doesn't have any debouncing in there (which you can add by just wrapping a not debounced re-com component).
Hm why not use track!
to update the internal state when the external changes, instead of having two copies of the external state? I guess problem is where do you call dispose!
to avoid leaking the component...
For future reference:
(defn dbfield [typ props st valfn changefn]
(let [int (r/atom @st)
ext (r/atom @st)
dbfn (debounce changefn)]
(fn [typ props st valfn changefn]
(when (not= @ext @st)
(reset! int @st)
(reset! ext @st))
[typ (assoc props
:value (valfn @int)
:on-change (fn [e]
(let [val (.. e -target -value)]
(dbfn st val)
(changefn int val))))])))
Hello, newbie question. I've got svg file and would like to render it as a component so I can apply styles to it. What would be the easiest way?
this is what I do... https://github.com/NyanCAD/Mosaic/blob/d9cbf2e7040258ff36227dca4148e4f90bd72f59/src/main/nyancad/mosaic/editor.cljs#L1039-L1052
@U2FRKM4TW your example code looks nice but I think I cannot apply it since my app is built with shadow-cljs