Finite State Machines for UI flows
Share
TL;DR: Model UI as a small set of explicit states and transitions. This prevents impossible states and makes flows easier to test.
Why FSMs help
UI flows like onboarding wizards, multi-step forms, or auth can end up in invalid combinations. With an FSM, only defined transitions are allowed.
Simple statechart
states:
idle -> loading on SUBMIT
loading -> success on OK
loading -> error on FAIL
error -> idle on RETRY
Reducer-based FSM in React
const chart = {
idle: { SUBMIT: "loading" },
loading: { OK: "success", FAIL: "error" },
error: { RETRY: "idle" },
success: {}
};
function next(state, event) {
return chart[state]?.[event] ?? state;
}
function Wizard() {
const [state, setState] = React.useState("idle");
const send = (evt) => setState(s => next(s, evt));
// render by state
}
Guards and data
Transitions can have conditions. Keep state and context separate so tests can verify both.
Testing transitions
- Assert the next state for each event.
- Test guard conditions with both allowed and blocked inputs.
FAQ
Do I need a library
No. Start with a reducer. Adopt a library later if you need visualization and tooling.
Is this overkill for small components
If your component has more than a couple of boolean flags and branches, an FSM usually pays off.
Cast this in your project
- Design Patterns Flashcards for robust modeling skills.
- React Interview Flashcards to drill UI patterns.
Image credit: Photo by Pixabay: https://www.pexels.com/photo/gray-scale-photo-of-gears-159298/