David Khourshid - @davidkpiano
JS Day Canarias
How should the system react?
What can happen in the system?
"States"
Asleep
Awake
Wake up
Visual formalisms are diagrammatic and intuitive, yet mathematically rigorous languages. Thus, despite their clear visual appearance, they come complete with a syntax that determines what is allowed, and semantics that determines what the allowed things mean.
David Harel
Callbacks
Event handlers
Ad-hoc logic
Ad-hoc logic
Reducer
EVENT
EVENT
EVENT
EVENT
State machine
EVENT
EVENT
EVENT
Statechart
Actors
npm install xstate
idle
searching
success
failure
SEARCH
RESOLVE
REJECT
SEARCH
SEARCH
npm install xstate
import { createMachine } from 'xstate';
const machine = createMachine({
initial: 'idle',
states: {
idle: {
on: { SEARCH: 'searching' }
},
searching: {
on: {
RESOLVE: 'success',
REJECT: 'failure',
}
},
success: {
on: { SEARCH: 'searching' }
},
failure: {
on: { SEARCH: 'searching' }
}
}
});
npm install xstate
import { createMachine } from 'xstate';
const machine = createMachine({
// ...
});
const searchingState = machine
.transition('idle', 'SEARCH');
searchingState.value;
// => 'searching'
npm install xstate
import { createMachine, interpret } from 'xstate';
const machine = createMachine({
// ...
});
const service = interpret(machine)
.onTransition(state => console.log(state))
.start();
service.send('SEARCH');
// State {
// value: 'searching',
// ...
// }
cart
shipping
contact
payment
confirmation
CHECKOUT
NEXT
NEXT
ORDER
PAYPAL
cart
shipping
contact
payment
confirmation
CHECKOUT
NEXT
NEXT
ORDER
PAYPAL
"How do I place an order?"
"How do I reach the confirmation state?"
cart
shipping
contact
payment
confirmation
CHECKOUT
NEXT
NEXT
ORDER
PAYPAL
"How do I place an order?"
"How do I reach the confirmation state?"
cart
shipping
contact
payment
confirmation
CHECKOUT
NEXT
NEXT
ORDER
PAYPAL
"How do I place an order where I enter shipping info?"
"How do I reach the confirmation state in which shipping info != null?"
+ shipping
import { createMachine } from 'xstate';
import { getShortestPaths } from '@xstate/graph';
const checkoutMachine = createMachine({
/* ... */
});
const shortestPathScenarios = getShortestPaths(checkoutMachine, {
events: {
// ...
}
});
console.log(shortestPathScenarios);
// {
// "cart": Object,
// "shipping": Object,
// "contact": Object,
// "payment": Object,
// "confirmed": Object
// }
G R A P H
This is where the magic happens
{
state: State,
paths: [
{
state: State,
segments: [
{ state: State, event: {/* ... */} },
{ state: State, event: {/* ... */} },
// ...
]
},
// ...
]
}
When app logic and state become
directed graphs...
State management problems become
graph theory problems
Which you can solve with well-known
algorithms.
David Khourshid - @davidkpiano