Skip to content

Counter State Machine

A counter state machine that maintains a numeric value that can be incremented, decremented, and reset, demonstrating how to store and update data within a state.

This example demonstrates:

  • Storing data within state using the data property
  • Self-transitions that preserve the state key but change the data
  • Using the addEventApi helper to create a clean API for transitions

Unlike the toggle example which had two distinct states, this counter example uses a single state (Active) with different data values, showing how state machines can maintain internal data.

import {
createMachine,
defineStates,
onLifecycle,
addEventApi,
} from "matchina";
export const createCounterMachine = () => {
const states = defineStates({
Active: (count: number = 0) => ({ count }),
});
// Create a machine with proper transitions
const machine = addEventApi(
createMachine(
states,
{
Active: {
increment: "Active",
decrement: "Active",
reset: () => () => states.Active(0),
},
},
states.Active()
)
);
onLifecycle(machine, {
Active: {
on: {
increment: {
effect: (ev) => {
ev.to.data.count = ev.from.data.count + 1;
},
},
decrement: {
effect: (ev) => {
ev.to.data.count = ev.from.data.count - 1;
},
},
},
},
});
return machine;
};
export type CounterMachine = ReturnType<typeof createCounterMachine>;
  • The counter uses transition functions that return a new state object with updated data
  • All transitions are self-transitions (staying in the Active state)
  • This pattern is common for state machines that need to track values but don’t have distinct behavioral states