Other state attributes
States can have various other attributes, most of which are useful for narrower cases.
State tags
State nodes can have tags, a list of strings that help describe the state node. Tags can be useful when categorizing different state nodes. For example, you can signify which state nodes represent “loading data” using a "loading"
tag and determine if a state contains those tagged state nodes with state.hasTag(tag)
:
ts
import {createMachine ,interpret } from 'xstate';constmachine =createMachine ({initial : 'idle',states : {idle : {on : {FETCH : 'loadingUser',},},loadingUser : {tags : ['loading'],},loadingFriends : {tags : ['loading'],},editing : {},},});constactor =interpret (machine ).start ();actor .state .hasTag ('loading'); // falseactor .send ('FETCH');actor .state .hasTag ('loading'); // true
ts
import {createMachine ,interpret } from 'xstate';constmachine =createMachine ({initial : 'idle',states : {idle : {on : {FETCH : 'loadingUser',},},loadingUser : {tags : ['loading'],},loadingFriends : {tags : ['loading'],},editing : {},},});constactor =interpret (machine ).start ();actor .state .hasTag ('loading'); // falseactor .send ('FETCH');actor .state .hasTag ('loading'); // true
Using tags can help you write more concise code. Instead of matching each actor individually:
ts
constisLoading =actor .state .matches ('loadingUser') ||actor .state .matches ('loadingFriends');
ts
constisLoading =actor .state .matches ('loadingUser') ||actor .state .matches ('loadingFriends');
You can group the actors by tag:
ts
constisLoading =actor .state .hasTag ('loading');
ts
constisLoading =actor .state .hasTag ('loading');
Defining tags
- Tags can be specified via an array, as
tag: ['tag1', 'tag2']
, or by a single string:tag: 'tag1'
. - Tags can be made type-safe in TypeScript by using typegen.
State meta
You can attach arbitrary data to any state by specifying it as meta
on the state node:
ts
import {createMachine ,interpret } from 'xstate';constfetchMachine =createMachine ({initial : 'pending',states : {pending : {on : {UNKNOWN_ERROR : 'errored',},after : {5000: 'timedOut',},},errored : {meta : {error : 'An unknown error occurred',},},timedOut : {meta : {error : 'Timeout error!',},},},});
ts
import {createMachine ,interpret } from 'xstate';constfetchMachine =createMachine ({initial : 'pending',states : {pending : {on : {UNKNOWN_ERROR : 'errored',},after : {5000: 'timedOut',},},errored : {meta : {error : 'An unknown error occurred',},},timedOut : {meta : {error : 'Timeout error!',},},},});
You can store anything in the meta
attribute; XState doesn’t monitor it or do anything with its contents.
The current state of the machine collects the meta
data of all of the state nodes, represented by the state value, and places them on an object where:
- The keys are the state node IDs
- The values are the state node
meta
values
For instance, if the machine above is in the timedOut
state, the meta
will be an object with the following shape:
js
{timedOut: {alert: 'Timeout error!'},}
js
{timedOut: {alert: 'Timeout error!'},}
State descriptions
You can add descriptive text to states with the description
attribute.
This text is used by the Visualizer and the Studio Editor to make the diagrams more descriptive.
ts
import {createMachine } from 'xstate';constmachine =createMachine ({initial : 'pending',description : `A machine that waits for something to happen, then completes`,states : {pending : {on : {FINISHED : 'complete',},description : `Waiting...`,},complete : {description : `Done!`,},},});
ts
import {createMachine } from 'xstate';constmachine =createMachine ({initial : 'pending',description : `A machine that waits for something to happen, then completes`,states : {pending : {on : {FINISHED : 'complete',},description : `Waiting...`,},complete : {description : `Done!`,},},});