Skip to content
Version: XState v5

Context

In XState, context is how you store data in a state machine actor.

The context property is available in all states and used to store data relevant to an actor. The context object is immutable, so you cannot directly modify it. Instead, for state machine logic, you can use the assign(...) action to update context.

The context property is optional; if the state machine only specifies finite states and no external contextual data, it may not need context.

import { createMachine } from 'xstate';

const feedbackMachine = createMachine({
// Initialize the state machine with context
context: {
feedback: 'Some feedback',
},
});

const feedbackActor = createActor(feedbackMachine);

feedbackActor.subscribe((state) => {
console.log(state.context.feedback);
});

feedbackActor.start();
// logs 'Some feedback'

Initial context​

Set the initial context of a machine in the context property of the machine config:

import { createMachine } from 'xstate';

const feedbackMachine = createMachine({
context: {
feedback: 'Some feedback',
rating: 5,
// other properties
},
});

The object you pass to context will be the initial context value for any actor created from this machine.

Lazy initial context​

Context can be initialized lazily by passing a function that returns the initial context value:

const feedbackMachine = createMachine({
context: () => ({
feedback: 'Some feedback',
createdAt: Date.now(),
}),
});

const feedbackActor = createActor(feedbackMachine).start();

console.log(feedbackActor.getSnapshot().context.createdAt);
// logs the current timestamp

Lazy initial context is evaluated per actor, so each actor will have its own context object.

Input​

You can provide input data to a machine’s initial context by passing an input property to the createActor(machine, { input }) function and using the input property from the first argument in the context function:

const feedbackMachine = createMachine({
context: ({ input }) => ({
feedback: '',
rating: input.defaultRating,
}),
});

const feedbackActor = createActor(feedbackMachine, {
input: {
defaultRating: 5,
},
}).start();

console.log(feedbackActor.getSnapshot().context.rating);
// logs 5

Learn more about input.

Updating context with assign(...)​

Use the assign(...) action in a transition to update context:

import { createMachine, assign } from 'xstate';

const feedbackMachine = createMachine({
context: {
feedback: 'Some feedback',
},
on: {
'feedback.update': {
actions: assign({
feedback: ({ event }) => event.feedback,
}),
},
},
});

const feedbackActor = createActor(feedbackMachine);

feedbackActor.subscribe((state) => {
console.log(state.context.feedback);
});

feedbackActor.start();

// logs 'Some feedback'

feedbackActor.send({
type: 'feedback.update',
feedback: 'Some other feedback',
});

// logs 'Some other feedback'

TypeScript​

You can strongly type the context of your machine in the types.context property of the machine config.

const machine = createMachine({
types: {} as {
context: {
feedback: string;
rating: number;
};
},
// Initial context
context: {
feedback: '',
rating: 5,
},
entry: ({ context }) => {
context.feedback; // string
context.rating; // number
},
});

Context cheatsheet​

Use our XState context cheatsheet below to get started quickly.

Initial context​

const machine = createMachine({
context: {
feedback: '',
},
});

Lazy initial context​

const machine = createMachine({
context: () => ({
feedback: '',
createdAt: Date.now(),
}),
});

Updating context with assign(...)​

const machine = createMachine({
context: {
feedback: '',
},
on: {
'feedback.update': {
actions: assign({
feedback: ({ event }) => event.feedback,
}),
},
},
});

Input​

const machine = createMachine({
context: ({ input }) => ({
feedback: '',
rating: input.defaultRating,
}),
});

const feedbackActor = createActor(machine, {
input: {
defaultRating: 5,
},
});