Xstate
by jpeter06
HTML
<script src="https://unpkg.com/xstate@4/dist/xstate.js"></script>
<button onclick="addEvent('next')">
NEXT
</button>
<button onclick="addEvent('reset')">
RESET?
</button>
<div>
state: <span id="state"></span>
</div>
JavaScript
const { createMachine, actions, assign, interpret } = XState;
//Context
const context = { count: 0, max:3 };
// Action
const addCont = assign({
count: (context, event) => context.count + 1
});
function logCont (context, event) {
console.log(`After: ${context.count}`)
};
const resetContext = assign({
count: 0
});
// Guard
function isFull(context, event) { console.log("isFull?",context.count)
return context.count >= context.max;
}
const zpMachine = createMachine({
id:'zp',
entry: ['init'], //Se ejecuta al comenzar
initial: 'off',
states: {
off: {
on: { 'next': { target: 'start' ,
actions:['addCont', 'logCont'] }, },
},
start: {
always:{ target: 'awake' ,cond: 'isFull'}, //Condición de paso a nuevo estado!!
on: { 'next': { target: 'start' ,
actions:'addCont' }, },
},
awake: {
on: { 'next': { target: 'walking', },
'reset': { target: 'off', },
},
},
walking: {
on: { 'next': { target: 'running', }, },
},
running: {
on: { 'next': { target: 'off', actions:'resetContext' }, },
},
},
},
{
actions: { addCont , logCont, resetContext},
guards: {isFull },
}
);
const zpMachinWC = zpMachine.withContext(context);
const actor = interpret(zpMachinWC).start();
// Fires whenever the state changes
const { unsubscribe } = actor.subscribe((state) => {
document.getElementById('state').innerHTML = state.value +
' count: ' + state.context.count +
' isFull: ' + isFull(state.context);
});
const addEvent = function (event){
console.log("new Event: ", event);
actor.send({ type: event});
}