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'
Context and 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.
Cheatsheet: initial contextβ
const machine = createMachine({
context: {
feedback: '',
},
});
Cheatsheet: lazy initial contextβ
const machine = createMachine({
context: () => ({
feedback: '',
createdAt: Date.now(),
}),
});
Cheatsheet: updating context with assign(...)β
const machine = createMachine({
context: {
feedback: '',
},
on: {
'feedback.update': {
actions: assign({
feedback: ({ event }) => event.feedback,
}),
},
},
});
Cheatsheet: inputβ
const machine = createMachine({
context: ({ input }) => ({
feedback: '',
rating: input.defaultRating,
}),
});
const feedbackActor = createActor(machine, {
input: {
defaultRating: 5,
},
});