@ivanbtrujillo
XState
XState es una librería para crear, interpretar y ejecutar state machines, escrita en Typescript.
ɛkssteɪt |
State machine
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.
¿Qué es una statechart?
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
Creando una state machine
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' } }
}
});
¿Cómo se usa?
/*
* 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
Visualizador
Herramienta para visualizar nuestra state machine en una statechart e interactuar con ella
Nuestra lightMachine
Extensión para VSCode
El contexto
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' } }
}
});
¿Cómo lo modificamos?
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
})
],
},
},
},
...
},
...
Contexto dinámico
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
¿Qué más podemos hacer?
- Ejecutar acciones sólo si se cumple una condición (guarded transitions)
- Ejecutar acciones cuándo entramos o salimos de una transición ( entry / exit actions)
- Invocar servicios
- Crear estados jerárquicos
- Invocar transiciones retrasadas (delayed transitions)
- Mucho más
¿Por qué elegir XState?
- Estados predecibles
- No se pueden introducir estados no-válidos
- Visualmente reproducibles (trabajo en equipo)
- Pensar en los estados y sus transiciones nos fuerza a pensar en la lógica antes de escribir código.
- Buena documentación
- La lógica puede discutirse con personas que no-desarrolladoras.
- Agnóstica
¿Dónde aprender?
-
https://xstate.js.org/ docs
- Charlas en React Finland: https://youtu.be/NmVZd-VWu3I
- Frontend Masters Courses (by David K Piano)
-
Eggead.IO Courses (Kyle Shevlin)
- Ejemplos: https://stately.ai/registry
El futuro
- XState V5
- https://stately.ai/
Demo
@ivanbtrujillo
Gracias
XState - Expero Night
By Iván BTrujillo
XState - Expero Night
- 1,933