@ivanbtrujillo
XState es una librería para crear, interpretar y ejecutar state machines, escrita en Typescript.
ɛkssteɪt |
Una state machine o maquina de estado define el comportamiento de un sistema que sólo puede estar en un estado para un momento dado.
Es un formalismo para modelar mediante diagramas una state machine
Off
On
Interruptor
Posibles estados: ON / OFF
Transiciones: ON -> OFF / OFF -> ON
Si está apagada y se alterna el interruptor, pasará a estar encendida
Si está encendida y se alterna el interruptor, pasará a estar apagada
Historias
npm install xstate
import { createMachine, interpret } from 'xstate';
const lightMachine = createMachine({
id: 'light', // identificador único
initial: 'off', // estado inicial
states: { // estados soportados (off, on)
off: { on: { TOGGLE: 'on' } }, // transiciones permitidas
on: { on: { TOGGLE: 'off' } }
}
});
/*
* Obtenemos un servicio como resultado de interpretar
* la máquina que hemos creado y la arrancamos
*/
const lightService = interpret(lightMachine).start();
Interpretamos la máquina y la arrancamos, obteniendo un servicio.
console.log(lightService.state.value); // off
Podemos ver el estado de nuestra máquina
Podemos enviar eventos
lightService.send('TOGGLE'); // on
Herramienta para visualizar nuestra state machine en una statechart e interactuar con ella
Nuestra lightMachine
Extensión para VSCode
El contexto es un estado extendido, y es una forma de representar los datos que acompañan a nuestro estado.
import { createMachine, interpret } from 'xstate';
const lightMachine = createMachine({
id: 'light',
initial: 'off',
context: {
color: 'yellow'
},
states: {
off: { on: { TOGGLE: 'on' } },
on: { on: { TOGGLE: 'off' } }
}
});
Utilizando acciones, que son funciones que se disparan cuando una transición ocurre. Disponemos de un tipo de acción especial llamada assign.
import { ..., assign } from 'xstate';
...
states: {
off: {
on: {
TOGGLE: {
target: "on", // Estado objetivo
actions: [
assign({
color: (context, event) => "red" // Asignamos el contexto
})
],
},
},
},
...
},
...
O pasarlo como parámetro al enviar nuestra acción
...
assign({
color: (context, event) => context.color === 'yellow' ? 'red' : 'yellow';
}),
...
lightService.send("TOGGLE", {
color: "purple"
});
...
assign({
color: (context, event) => event.color
}),
...
Podemos calcular el nuevo contexto en base al valor actual
@ivanbtrujillo