计数器
This counter app example demonstrates a counter that has a single 'active' state and two possible events:
'INC'- an intent to increment the current count by 1'DEC'- an intent to decrement the current count by 1
The count is stored in context.
import { createMachine, interpret, assign } from 'xstate';const increment = (context) => context.count + 1;const decrement = (context) => context.count - 1;const counterMachine = createMachine({initial: 'active',context: {count: 0},states: {active: {on: {INC: { actions: assign({ count: increment }) },DEC: { actions: assign({ count: decrement }) }}}}});const counterService = interpret(counterMachine).onTransition((state) => console.log(state.context.count)).start();// => 0counterService.send('INC');// => 1counterService.send('INC');// => 2counterService.send('DEC');// => 1
Modeling Min and Max
With guards, we can model min and max by preventing transitions on the 'DEC' and 'INC' events on certain values, respectively:
// ...const isNotMax = (context) => context.count < 10;const isNotMin = (context) => context.count >= 0;const counterMachine = createMachine({initial: 'active',context: {count: 0},states: {active: {on: {INC: {actions: assign({ count: increment }),cond: isNotMax},DEC: {actions: assign({ count: decrement }),cond: isNotMin}}}}});// ...// assume context is { count: 9 }counterService.send('INC');// => 10counterService.send('INC'); // no transition taken!// => 10
