This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # beginners (31)
- # boot (24)
- # braid-chat (17)
- # cider (4)
- # cljs-dev (33)
- # cljsrn (5)
- # clojure (79)
- # clojure-austin (1)
- # clojure-poland (229)
- # clojure-russia (51)
- # clojure-uk (3)
- # clojurescript (68)
- # core-async (1)
- # core-matrix (1)
- # datomic (18)
- # editors (24)
- # emacs (7)
- # hoplon (118)
- # jobs (1)
- # jobs-discuss (1)
- # juxt (7)
- # off-topic (16)
- # om (121)
- # onyx (3)
- # parinfer (224)
- # protorepl (3)
- # re-frame (29)
- # reagent (1)
- # rethinkdb (2)
- # ring (1)
- # spacemacs (2)
- # untangled (182)
Hi, am I right re-frame doesn't play well with reagent cursors? I can create a cursor but when I update it using
reset! UI doesn't redraw. Should I use dispatch instead?
hm, sorry. seems to work fine. I was creating cursor on resolved value @
(let [v @x y (r/cursor v )] ...(reset! @y 42))
I don't understand how does this works and which is preferred: using handlers and dispatch or cursors and reset! ?
That was me being diplomatic. What I really wanted to say was that cursors are awful, and a horrible blight and that you should never use them (outside of toy applications) and absolutely never with re-frame. Ever.
BTW, your code
reset! @y 42 should be
reset! y 42. But now I just feel dirty for having facilitated cursor use.
Lookin at re-com accepting atoms as
:model i thought that's the intended scenario. You have one
ratom with form state and a lot of inputs. You pass cursor for specific value to
:model and don't bother about updating the ratom object.
The API of various components use a pattern where
ratoms are used to pass information "in" and
callbacks are used to communicate "out" changes of state
If you think about it, the re-com components are using a variation of what re-frame does
Can someone help clarify why it’s incorrect to deref a subscription in the let block of the outer function of a component, versus deref’ing inside the inner render function?
If you do this, say, for an
(defn component  (let [my-val (deref (subscribe [:value]) (fn  [:div my-val])))
input :type “text”only the last keystroke will register and render into the input box on change. The outer function is called once for the component, and the subscribe is registered to re-run the inner render function any time its input signal changes. For “convenience” I wanted to try to deref in the let block, so I don’t have to do something like …
All over the render fn when I have multiple uses of the ratom. I see why it’s wrong, but I dont fully understand why it’s wrong. The inner render is wrapped in a reaction to produce a new signal any time a deref’d ratom changes… so because there are no
[:div @my-val [.p @my-val] [.p (count @my-val]]
@inside the render, the reaction never triggers. The outer block is invoked once, and if you deref a ratom immediately… ???
I don’t see why a
input :type “text” :value my-val psuedo “works”, always updating to display the last character input, but never remembering previous… should it not always display “”, or the default value provided, and never change?
> Can someone help clarify why it’s incorrect to deref a subscription in the let block of the outer function of a component, versus deref’ing inside the inner render function? From what you write afterwards, I think you do understand ... but I'll repeat it back to you ... The outer function is run once. The inner render is run every time one of its "inputs" changes (inputs can be either props or ratoms). So if you subscribe in the outer and then immediately deref you are obtaining the initial *value* of the subscription. But then, because outer is only ever run once, that's it - that value will never change. That value remains the initial value of the subscription forever. There's obviously a difference between a "value" and a "ratom-containing-a-value". The subscription is delivering "ratom-containing-value" (which is a Signal) and, by derefing it, you are extracting the immutable value within it which is, of course, not a Signal. An inner render will respond to changes in a "ratom-contain-value" by rerendering, but a value can't ever change. Perhaps you'd feel better about this kind of an arrangement ...
(defn component  (let [my-val (subscribe [:value])] (fn  (let [v @my-val] ;; <--- you can do this INSIDE the inner [:div v [:p v] [:p v]])))
Or alternatively ... you can do it via two components, a parent one which sources the data and and child one which does the rendering.
(defn child [v] [:div v [:p v] [:p v]]) (defn parent  (let [my-val (subscribe [:value])] (fn  [child @my-val]))) ;; derefed
Regarding your misbehaving
input, you might need to post a gist. Not enough information given to explain why you see the particular behavior you do.
BTW, although you do appear to have "got it", something is still obviously puzzling you, so you might still want to browse back over: https://github.com/Day8/re-frame/wiki/When-do-components-update%3F
hey many thanks @mikethompson, you’ve been a big help. Also, I’m growing to appreciate the simplicity reframe brings to overblown and imposing architectures. Job well done I’d say.
@mikethompson: have you thought about making your with subs macro a more exposed part of re-frame? I thought that was a really good idea and it solves the idea you just described above while taking care of the possible memory leak
you could even take it one step further and make a defui macro that has 3 different airities. [name child] -> turns into a simple type one component which takes no props and just renders the child [name props child] -> also a type one component which takes props and renders the child [name props subs child] -> creates a type two component which does essentially what with-subs does