Escaping v-if and Flag Hell — Building a Screen-Transition State Machine with Pinia
"The submit button got pressed twice, causing a duplicate registration." "The screen broke because someone interacted with it mid-animation." I think bugs like these almost always come down to holding "what phase the screen is currently in" as a scattered collection of flags.
With N flags, you end up with 2^N possible states, which is a breeding ground for bugs.
What this lightning talk proposes is: stop adding more flags, and instead consolidate the screen's state into just one "where am I right now" value plus a map of "where can I go from here." In other words, a state machine (not a novel concept — this is an old idea).
I'll show, with a self-built demo, how this alone solves rapid double-clicking, duplicate submissions, and misfires during async processing. It's nothing more than putting a transition map and a single state-switching function inside a defineStore.
I'll actually trigger rapid clicks on an answer button and a timeout interrupt mid-animation, and show how the state machine blocks them.
What you'll take home applies broadly to any UI involving "async processing + the user pressing a button" — wizards, checkout flows, uploads, and the like.
Now, when it comes to state machine libraries, XState (with its official @xstate/vue) is the standard choice. This talk, however, writes things directly in Pinia without bringing in XState, and shows a way to eliminate unintended behavior during async processing by re-checking state.
(XState's own creator has said that a library isn't strictly necessary for state machines — this talk is essentially a live demonstration of that "library-free" approach.)
https://dev.to/davidkpiano/you-don-t-need-a-library-for-state-machines-k7h
I'll also address the "then why not just use XState?" question head-on: what I'm covering here is just "single phase + guarded transitions," so I won't be using XState's headline features (hierarchical states, parallel states, actors, SCXML, the visualizer). I'll also draw the line showing when you actually do need XState — once your states become hierarchical or parallel, or once you want to handle async work declaratively via actors.
northprint
Escaping v-if and Flag Hell — Building a Screen-Transition State Machine with Pinia
"The submit button got pressed twice, causing a duplicate registration." "The screen broke because someone interacted with it mid-animation." I think bugs like these almost always come down to holding "what phase the screen is currently in" as a scattered collection of flags.
With N flags, you end up with 2^N possible states, which is a breeding ground for bugs.
What this lightning talk proposes is: stop adding more flags, and instead consolidate the screen's state into just one "where am I right now" value plus a map of "where can I go from here." In other words, a state machine (not a novel concept — this is an old idea).
I'll show, with a self-built demo, how this alone solves rapid double-clicking, duplicate submissions, and misfires during async processing. It's nothing more than putting a transition map and a single state-switching function inside a defineStore.
I'll actually trigger rapid clicks on an answer button and a timeout interrupt mid-animation, and show how the state machine blocks them.
What you'll take home applies broadly to any UI involving "async processing + the user pressing a button" — wizards, checkout flows, uploads, and the like.
Now, when it comes to state machine libraries, XState (with its official @xstate/vue) is the standard choice. This talk, however, writes things directly in Pinia without bringing in XState, and shows a way to eliminate unintended behavior during async processing by re-checking state.
(XState's own creator has said that a library isn't strictly necessary for state machines — this talk is essentially a live demonstration of that "library-free" approach.)
https://dev.to/davidkpiano/you-don-t-need-a-library-for-state-machines-k7h
I'll also address the "then why not just use XState?" question head-on: what I'm covering here is just "single phase + guarded transitions," so I won't be using XState's headline features (hierarchical states, parallel states, actors, SCXML, the visualizer). I'll also draw the line showing when you actually do need XState — once your states become hierarchical or parallel, or once you want to handle async work declaratively via actors.
