History state

A history state is a pseudostate, meaning that a state machine can’t rest in a history state. When a transition that leads to a history state happens, the history state itself doesn’t become active, rather the “most recently visited state” becomes active. It is a way for a compound state to remember (when it exits) which state was active, so that if the compound state ever becomes active again, it can go back to the same active substate, instead of blindly following the initial transition.

There are two types of history states, deep history states and shallow history states. A deep history remembers the deepest active state(s) while a shallow history only remembers the immediate child’s state.

Notation

A history state is denoted by way of a capital letter H enclosed by a circle.

A history state is deep if it is followed by an asterisk *.

SCXML

SCXML supports both deep and shallow history states by way of the <history> element:

<state id="A" initial="B">
  <history id="A_AGAIN">
    <transition target="C"/>
  </history>
  <state id="B"/>
  <state id="C"/>
  <state id="D"/>
</state>

<!-- elsewhere -->
<transition target="A_AGAIN"/>

Here we have a compound state A with substates B, C and D.

  • Whenever state A exits, it remembers which of the states, B, C or D was last visited.
  • If a transition targets “A_AGAIN”, then the last visited state is entered instead.
  • If a transition targets “A_AGAIN” before state A has had the chance to remember anything, then A_AGAIN’s transition to C is taken.

XState

In XState, a history state is declared using both type: "history" and the history attribute (optional). It can be set to "shallow" for shallow history, and "deep" for deep history. A history state may declare a target for the initial history.

"A": {
  initial: "B"
  states: {
    A_AGAIN: {
      type: "history",
      history: "deep", // "shallow" by default
      target: "C"
    },
    B: {},
    C: {},
    D: {}
  }
}

// elsewhere
on: {
  something: "A_AGAIN"
}

Here we have a compound state A with substates B, C and D.

  • Whenever state A exits, it remembers which of the states, B, C or D was last visited.
  • If a transition targets “A_AGAIN”, then the last visited state is entered instead.
  • If a transition targets “A_AGAIN” before state A has had the chance to remember anything, then A_AGAIN’s transition to C is taken.