reagent

A minimalistic ClojureScript interface to React.js http://reagent-project.github.io/
Rebecca Bruehlman 2020-12-31T12:41:47.458100Z

So I have the following set of actions I want to have happen in my app: • Turn some circles yellow one second after the other • Then turn the circles red for a half second or so before turning grey • In between the circles being red and grey, issue an event (It’s meant to simulate a countdown and then a camera flash). I have the following code:

(defn timeout [event time]
  (js/setTimeout
   (fn []
     (rf/dispatch event))
   time))

(rf/reg-fx
 :timeout-fx
 (fn [args]
   (if (= (type args) map)
     (timeout (:event args) (:time args))
     (doseq [event args]
       (timeout (:event event) (:time event))))))

(rf/reg-event-db
 ::set-timer
 (fn [db [_ val]]
   (camera-q/set-timer db val)))

(rf/reg-event-fx
 ::countdown
 (fn []
   (doseq [i [1 2 3]]
     (timeout [::set-timer i] (* 1000 i)))))

(rf/reg-event-fx
 ::begin-countdown
 (fn []
   {:fx [[:dispatch [::countdown]]]
    :timeout-fx [{:event [::set-timer 4]
                  :time 3500}
                 {:event [::update-active-photo]
                  :time 3500}
                 {:event [::set-timer 0]
                  :time 4300}
                 ]}))

# components subscribe to timer value that determines color, blah blah
It …. works, but it feels wrong? I’m thinking there must be a better, more idiomatic way of chaining these events? (I’m also unhappy with my poor man’s implementation of multiarity with timeout-fx, but wasn’t sure how else to do it.)

p-himik 2020-12-31T12:45:21.458200Z

A few things: - camera-q/set-timer should not have any side effects - The ::countdown event handler should use the :timeout-fx effect instead of calling timeout directly - The ::begin-countdown event handler should ideally either use :fx for both :dispatch and :timeout-fx or just have both :dispatch and :timeout-fx at the top level, without :fx Apart from that, I don't see any issues.

Rebecca Bruehlman 2020-12-31T12:48:10.458400Z

Thanks! Last two points make sense to me. camera-q/set-timer is modifying the db (it’s just (assoc-in db [blah blah blah] val)…. so if I’m not modifying the db there, where would I issue that necessary change?

p-himik 2020-12-31T12:49:25.458600Z

You're not modifying the db there, you're creating a brand new value since the data structure is immutable. And it's completely fine, it's how it's supposed to be. :)

Rebecca Bruehlman 2020-12-31T12:50:14.458800Z

True, that. Gotta beat the Python out of my brain 😉 Appreciate the help!

p-himik 2020-12-31T12:52:14.459Z

Ah, a fellow "Python expat". :D Any time.

afleck 2020-12-31T14:08:57.460800Z

what’s the minimum version of React compatible with reagent 1.0.0? can I use react 16.14.0 or do I need 17.x?

1👍1➕
2020-12-31T14:54:39.461700Z

Is it possible to tell reagent to render some component as a PureComponent ? Or can it check that automatically?

emccue 2020-12-31T20:21:11.462800Z

(defn timeout [event time]
  (js/setTimeout
   (fn []
     (rf/dispatch event))
   time))

(rf/reg-fx
 :timeout-fx
 (fn [args]
   (timeout (:event args) (:time args))))

(rf/reg-event-db
 ::set-timer
 (fn [db [_ val]]
   (camera-q/set-timer db val)))

(rf/reg-event-fx
 ::countdown
 (fn []
   (doseq [i [1 2 3]]
     (timeout [::set-timer i] (* 1000 i)))))

(rf/reg-event-fx
 ::begin-countdown
 (fn []
   {:fx [[:dispatch [::countdown]]
         [:timeout-fx {:event [::set-timer 4]
                       :time 3500}
         [:timeout-fx {:event [::update-active-photo]
                       :time 3500}]
         [:timeout-fx {:event [::set-timer 0]
                       :time 4300}]]}))

emccue 2020-12-31T20:24:28.463300Z

you can just use the fx key instead of that multiple arity stuff

emccue 2020-12-31T20:25:01.463900Z

and really, for stuff like the timer value

emccue 2020-12-31T20:25:41.464700Z

that can be computed based on the current time, so ymmv with regards to just setting the current time in the model and computing

emccue 2020-12-31T20:27:14.465Z

and i missed that being explained in the replies

1😄
emccue 2020-12-31T20:27:22.465300Z

meh