Skip to content
Version: XState v4

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):

import { createMachine, interpret } from 'xstate';

const machine = createMachine({
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loadingUser',
},
},
loadingUser: {
tags: ['loading'],
},
loadingFriends: {
tags: ['loading'],
},
editing: {},
},
});

const actor = interpret(machine).start();

actor.state.hasTag('loading'); // false

actor.send('FETCH');

actor.state.hasTag('loading'); // true

Using tags can help you write more concise code. Instead of matching each actor individually:

import { createMachine, interpret } from 'xstate';

const machine = createMachine({
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loadingUser',
},
},
loadingUser: {
tags: ['loading'],
},
loadingFriends: {
tags: ['loading'],
},
editing: {},
},
});

const actor = interpret(machine).start();

const isLoading =
actor.state.matches('loadingUser') || actor.state.matches('loadingFriends');

You can group the actors by tag:

import { createMachine, interpret } from 'xstate';

const machine = createMachine({
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loadingUser',
},
},
loadingUser: {
tags: ['loading'],
},
loadingFriends: {
tags: ['loading'],
},
editing: {},
},
});

const actor = interpret(machine).start();

const isLoading = 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:

import { createMachine, interpret } from 'xstate';

const fetchMachine = 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:

{
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.

import { createMachine } from 'xstate';

const machine = createMachine({
initial: 'pending',
description: `A machine that waits for something to happen, then completes`,
states: {
pending: {
on: {
FINISHED: 'complete',
},
description: `Waiting...`,
},
complete: {
description: `Done!`,
},
},
});