Context
In XState, context
is how you store data in a state machine actor.
context
is a special property available in all states and used to store data relevant to the state machine. The context
object is immutable, so you cannot directly modify it. Instead, use the assign(...)
action to update context
.
The context
property is optional; if the state machine only specifies finite states, it may not need context
.
import { createMachine } from 'xstate';
const feedbackMachine = createMachine({
// Initialize the state machine with context
context: {
feedback: 'Some feedback',
},
});
const feedbackActor = interpret(feedbackMachine);
feedbackActor.subscribe((state) => {
console.log(state.context.feedback);
});
feedbackActor.start();
// logs 'Some feedback'
↓Jump to learning more about context in XState↓
Using context in Stately Studio​
- Coming soon… setting initial values
- Coming soon… updating context with assign
- Coming soon… JS/TS export
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 = interpret(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 interpret(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 = interpret(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 = interpret(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​
const machine = createMachine({
schema: {} as {
context: {
feedback: string;
rating: number;
};
},
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 = interpret(machine, {
input: {
defaultRating: 5,
},
});