A minimalistic ClojureScript interface to React.js
simongray 2020-04-11T10:18:58.143300Z

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?

simongray 2020-04-11T10:21:41.144200Z

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?

juhoteperi 2020-04-11T10:30:01.146300Z

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

simongray 2020-04-11T10:30:56.146800Z

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
    [:button {:on-click #(swap! ra vary-meta update :i inc)}]
    (-> @ra meta :i str)]
    [:button {:on-click #(swap! rc vary-meta update :i inc)}]
    (-> @rc meta :i str)]])

simongray 2020-04-11T10:31:41.147Z

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.

juhoteperi 2020-04-11T10:41:38.147300Z

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.

juhoteperi 2020-04-11T10:41:56.147500Z

RCursor only notifies listeners if the value changes

juhoteperi 2020-04-11T10:43:48.147800Z

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.

juhoteperi 2020-04-11T10:44:07.148Z

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

simongray 2020-04-11T10:45:35.148500Z

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-himik 2020-04-11T10:49:18.148700Z

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.

simongray 2020-04-11T10:50:40.149300Z

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.

simongray 2020-04-11T10:51:14.149500Z

seems like a great way to semantically separate content

p-himik 2020-04-11T10:52:13.149700Z

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


Good things to know!

juhoteperi 2020-04-11T13:14:33.150900Z

Yeah I agree with @p-himik 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.