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.
Implementation details
Section titled “Implementation details”Unlike the toggle example which uses two distinct states, counter uses a single state (Active) with different data values. Self-transitions preserve the state key but return a new state object with updated data.
import { createMachine, defineStates, setup, effect, createStoreMachine, addStoreApi, withSubscribe,} from "matchina";
export const createCounterMachine = () => { const states = defineStates({ Active: undefined, Inactive: undefined, });
const store = createStoreMachine( { count: 0 }, { increment: () => (change) => ({ count: change.from.count + 1 }), decrement: () => (change) => ({ count: change.from.count - 1 }), reset: () => () => ({ count: 0 }), } ); const storeWithApi = addStoreApi(withSubscribe(store));
const machine = createMachine( states, { Active: { increment: "Active", decrement: "Active", reset: "Active", deactivate: "Inactive", }, Inactive: { activate: "Active", }, }, "Active" );
setup(machine)( effect((ev) => { if (ev.to.is("Active") && ev.type in storeWithApi.api) { (storeWithApi.api as any)[ev.type](); } }) );
// Encapsulate store and expose methods on machine const enhancedMachine = Object.assign(machine, { store: storeWithApi, increment: () => storeWithApi.api.increment(), decrement: () => storeWithApi.api.decrement(), reset: () => storeWithApi.api.reset(), getCount: () => storeWithApi.getState().count, });
return enhancedMachine;};
export type CounterMachine = ReturnType<typeof createCounterMachine>;- Storing data within state using the
dataproperty - Self-transitions that preserve the state key but change the data
addEventApifor a clean event-dispatch API