Vue FesJapan 2026
The main visual of Vue Fes Japan 2026. It features a silhouette of a V, representing Vue, and a circle, representing the Japanese flag, side by side. The colors are deep matcha-like shades derived from the two colors, and the circle features a Japanese gold marbling pattern.
OtemachiPlace Hall & Conference

Speaker

Cybozu Track
16:35 - 17:50
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.

northprint

Affiliation
ICS INC.
Title
Front-end Engineer

northprint

Affiliation
ICS INC.
Title
Front-end Engineer

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.