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.)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.
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?
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. :)
True, that. Gotta beat the Python out of my brain 😉 Appreciate the help!
Ah, a fellow "Python expat". :D Any time.
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
?
Is it possible to tell reagent to render some component as a PureComponent
? Or can it check that automatically?
(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}]]}))
you can just use the fx key instead of that multiple arity stuff
and really, for stuff like the timer value
that can be computed based on the current time, so ymmv with regards to just setting the current time in the model and computing
and i missed that being explained in the replies
meh