Fork me on GitHub
#reagent
<
2020-04-11
>
simongray10:04:58

Reacting to metadata changes? it seems like it’s perfectly possible to get re-renders when the metadata of the contents of a ratom changes, but if I create a cursor to that same content, I don’t get any re-renders. It seems to me like ratoms and cursors should act the same in this regard, so why the difference?

simongray10:04:41

to be fair, me trying to use metadata in this way might be trying to hack the system, I just found it odd that it would work for ratoms, but not for cursors. I guess they have different equality checks?

juhoteperi10:04:01

Some code example could be helpful to explaining this. How do you update the metadata on Ratom value?

simongray10:04:56

Here’s an example:

(defonce ra
  (r/atom (with-meta [] {:i 0})))

(defonce ra-for-rc
  (r/atom {:a {:b {:c (with-meta [] {:i 0})}}}))

(defonce rc
  (r/cursor ra-for-rc [:a :b :c]))

(defn ratom-vs-cursor
  []
  [:div
   [:p
    [:button {:on-click #(swap! ra vary-meta update :i inc)}]
    (-> @ra meta :i str)]
   [:p
    [:button {:on-click #(swap! rc vary-meta update :i inc)}]
    (-> @rc meta :i str)]])

simongray10:04:41

If I do with-meta it doesn’t work either, but if I update the actual value at the same time, it will update just fine. It just doesn’t react to metadata updates, unlike the ratom.

juhoteperi10:04:38

RAtom implementation will notify change listeners (e.g. components and other reactions) whenever swap or reset is called, even if the value didn't change.

juhoteperi10:04:48

This is so that RCursor doesn't trigger changes when the RAtom it depends on changes, but the value on the cursor path didn't change.

juhoteperi10:04:07

Not sure if it would make sense to always trigger when calling reset/swap on cursor. But this is very minor oddity.

simongray10:04:35

I see. Thanks a lot for investigating. That sucks, because it kind of prevents me from doing something I had in mind (using metadata for incidental information like indices) if it can’t apply broadly.

p-himik10:04:18

I imagine you would get into trouble with metadata sooner or later either way - it's finicky, not many libraries or functions try to preserve it.

simongray10:04:40

yeah, even clojure.core isn’t too consistent about it, but I just love the idea of attaching, well metadata like “what is the current index being viewed” to real data like a vector of content.

simongray10:04:14

seems like a great way to semantically separate content

p-himik10:04:13

> content Metadata is not for that. It's a great way to shoot yourself in the foot. :)

juhoteperi13:04:33

Yeah I agree with @U2FRKM4TW here. The selected index being viewed etc. is real data just like the vector or something, just place it it a map with the other data.