reagent-project / reagent

A minimalistic ClojureScript interface to React.js
http://reagent-project.github.io/
MIT License
4.75k stars 415 forks source link

reagent/cursor and swap-vals! #428

Open pepperblue opened 5 years ago

pepperblue commented 5 years ago

I don't know, if reagent/cursor was intended to work with "swap-vals!" ... Using

clojure "1.10.0" clojurescript "1.10.520" reagent "0.8.1"

the behaviour is not as I would expect it to be:

cljs.user> (def foo (reagent/atom {:bar {:baz "qux"}}))

'cljs.user/foo

cljs.user> (def foobar (reagent/cursor foo [:bar]))

'cljs.user/foobar

cljs.user> (swap-vals! foobar assoc :baz "quux") [nil {:baz "quux"}] cljs.user> @foo {:bar {:baz "qux"}} cljs.user> @foobar {:baz "qux"}

Deraen commented 5 years ago

No, the implementation doesn't work with reset-vals! or swap-vals!. I hadn't really noticed those methods though they were implemented in September 2017.

The implementation wouldn't be hard, for JVM Clojure anyway, since swapVals method is part of IAtom2 (great naming) interface, so cursors could implement correct logic there. But looking at ClojureScript code, swap-vals! has been implemented using reset-vals! which directly modifies Atom state property: https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L4478-L4491

This means that it is not currently possible to implement this for cursors in ClojureScript, because when cursor state is updated, also the host atom should be updated.

pepperblue commented 5 years ago

Thanks for the explanation :-)

Deraen commented 5 years ago

Lets keep this open so that the explanation is easier to find, if someone else stumbles upon this.

And also to help me remember to look into checking if Cljs should support extending reset/swap-vals! implementation.

kumar88kanishk commented 4 years ago

Hey thanks, i am a newbie in clojure and was reading up reagent cook book and was wondering is cursors could be set. This cleared my doubts, i agree to keep this open and may be it could be implemented later on