When actions fire in xstate

michalbryxi

Michal Bryxí

Posted on November 13, 2020

When actions fire in xstate

While working with statecharts in the popular xstate library I fell into a trap of not understanding how and when are actions fired.

Most of the time it does not really matter. Until it does. That until happened when I tried to "smartly" use transient transitions.

Given following statechart:

const machine = Machine(
  {
    initial: 'idle',
    context: {
      winning: 'heads',
      selected: 'tails'
    },
    states: {
      idle: {
        on: {
          SELECT: [
            { target: 'playing' }
          ]
        },
      },
      playing: {
        // It might seem that entry level action fires first.
        entry: ['flipCoin'],
        on: {
          '': [
            // And *after* that the guard is checked.
            // But this is not how it works.
            { target: 'score', cond: 'isScore' },
            { target: 'nope' }
          ]
        }
      },
      nope: {
        type: 'final'
      },
      score: {
        type: 'final'
      },
    }
  }, {
    guards: {
      isScore(context) {
        console.log('guard isScore');
        return context.selected === context.winning;
      },
    },
    actions: {
      flipCoin(context) {
        context.selected = 'heads';
        console.log('action flipCoin');
      }
    }
  }
);
Enter fullscreen mode Exit fullscreen mode

one might assume that given the entry action called flipCoin, which will change state selected='heads' the guard isScore will return true and thus we will end in the score final state.

But this is not how things work. According to the documentation:

Actions are not immediately triggered. Instead, the State object returned from machine.transition(...) will declaratively provide an array of .actions that an interpreter can then execute.

So in my head:

After event is sent to xstate, the next state of the statechart is determined based on current context before any actions are fired.


Photo by Clyde He on Unsplash

💖 💪 🙅 🚩
michalbryxi
Michal Bryxí

Posted on November 13, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Supervising XState Machines with Redux
When actions fire in xstate
xstate When actions fire in xstate

November 13, 2020

Pure UI using Xstate and ReactJS