Xstate: Support targetless transitions

Created on 11 Jun 2018  路  1Comment  路  Source: davidkpiano/xstate

(Posting here after a suggestion from the forum on Spectrum)

It would be great if xstate could support targetless transitions, where an event can be consumed (perhaps emitting actions) without a change of state. Here's an example machine plus some transitions (in 3.3.2, the final transition displays an error):

const { Machine } = require('xstate');

const machine = Machine({
    key: 'test',
    initial: 'first',
    states: {
        first: {
            onEntry: 'enter',
            onExit: 'exit',
            initial: 'one',
            states: {
                one: {
                    on: {
                        NEXT: 'two',
                    },
                },
                two: {},
            },
            on: {
                NEXT: [
                    {
                        actions: ['ping'],
                    },
                ],
            },
        },
    },
});

const log = (ix, state) => {
    console.log(`${ix}\n\n${JSON.stringify(state, null, 4)}\n\n`);
};

const state1 = machine.initialState;

log(1, state1);

const state2 = machine.transition(state1, 'NEXT');

log(2, state2);

const state3 = machine.transition(state2, 'NEXT');

log(3, state3);

This feature does appear to be part of SCXML (at least, "targetless transition" is defined and used: I confess to not reading the spec in detail).

I guess it could be useful in some machines to be able to swallow an event even if no actions are emitted, as it would stop the event bubbling to an ancestor.

Using a transition config object, minus the target property, would seem a reasonable way to define a targetless transition. Breaking change? Potentially in minor edge cases, I guess.

enhancement 馃搼 SCXML

Most helpful comment

Done. There are two ways to define a targetless transition:

{
  on: {
    EVENT: {
      // empty target
      '': { actions: ['doSomething'] }
    }
  }
}

// or within a conditional array:
{
  on: {
    // no target
    EVENT: [{ actions: ['doSomething'] }]
  }
}

>All comments

Done. There are two ways to define a targetless transition:

{
  on: {
    EVENT: {
      // empty target
      '': { actions: ['doSomething'] }
    }
  }
}

// or within a conditional array:
{
  on: {
    // no target
    EVENT: [{ actions: ['doSomething'] }]
  }
}
Was this page helpful?
0 / 5 - 0 ratings