I decided to use state machines to model the state of web apps after I find myself repeating the same pattern over and over again: a bunch of boolean flags like "loading", "load-failed", "saving", etc, and always performing some actions when these flags are toggled on and off in the code. This is exactly what FSM and StateCharts are designed for.
https://www.youtube.com/watch?v=VU1NKX6Qkxc given by the creator of xstate summarizes it really well.
It takes some time to shift the mindset from "using a bunch of boolean flags" to "using a state machine". But once one gets familiar with it, the huge payback is definitely worth the time invested. And the more complex the application states are, the more one benefits from it.
> but there's some friction in fitting with the re-frame event loop
you can use the https://lucywang000.github.io/clj-statecharts/docs/integration/re-frame/ provided by clj-statecharts, so that you can update the state machine just using re-frame events and no need to call fsm/transition
yourself. This almost feels "seamless" because after you defines the state machine, you never need to call it again, just dispatch regular events, and process the events data in the actions.
I was looking through re-frame CHANGELOG and found this
1.1.0 (2020-08-24)
Added
re-frame now guarantees that a :db effect, if present, will be actioned before any other sibling effects. re-frame continues to provide no guarantees about the order in which other effects will be actioned.
I was pretty sure that re-frame already guaranteed that :db
is actioned first before 1.1.0
. Am I wrong?You are. You're probably thinking of this effect map:
{:db (...)
:dispatch [...]}
Here, the effects are unordered. But the event is handled after the :db
effect is handled simply because :dispatch
doesn't handle the event itself - it just schedules it.