Traffic Light State Machine
Multi-state machine with automatic transitions demonstrating cyclic state flows.
Use Case
This example models a traffic light with a red → green → yellow → red cycle. It demonstrates how to handle multiple states with cyclic transitions, making it useful for:
- Traffic light controllers
- Multi-step workflows with repeating cycles
- Game state loops (menu → playing → game over → menu)
- Carousel or slideshow controls
Complete Code
import { createMachine } from "xstate";
// Define statestype TrafficState = "red" | "yellow" | "green";
// Define eventstype TrafficEvent = { type: "TIMER" };
// Create machineconst trafficMachine = createMachine<TrafficState, TrafficEvent>({ id: "traffic", initial: "red", states: { red: { on: { TIMER: "green", }, }, green: { on: { TIMER: "yellow", }, }, yellow: { on: { TIMER: "red", }, }, },});
// Usage with timerlet state = trafficMachine.initialState;console.log(state); // 'red'
// Simulate automatic transitionssetInterval(() => { state = trafficMachine.transition(state, { type: "TIMER" }); console.log(`Light changed to: ${state}`);}, 3000); // Change every 3 secondsCode Explanation
-
Multiple states - Defines three distinct states (
'red','yellow','green') instead of just two, showing how state machines scale beyond binary toggles. -
Cyclic transitions - Each state transitions to the next state in the cycle when receiving a
TIMERevent, creating a continuous loop. -
Timer integration - Uses
setIntervalto automatically trigger state transitions, demonstrating how external timing mechanisms integrate with state machines. -
Deterministic behavior - No matter how many cycles complete, the state is always predictable based on the number of
TIMERevents received.
Key Concepts
- Multi-state machines: Not limited to two states - model complex workflows with many states
- Cyclic transitions: States can form loops, returning to previous states in a predictable pattern
- External triggers: State machines react to external events like timers, user actions, or network responses
- Deterministic: Same sequence of events always produces the same sequence of states
Variations
Different timing per state:
const timings = { red: 5000, green: 4000, yellow: 2000 };let state = trafficMachine.initialState;
function scheduleNext() { setTimeout(() => { state = trafficMachine.transition(state, { type: "TIMER" }); console.log(`Light: ${state}`); scheduleNext(); }, timings[state]);}
scheduleNext();Next Steps
- Form Validation Example - Learn about guards and conditional transitions
- Basic State Machine - Return to foundational concepts
- API Documentation - Explore advanced features like actions and context