上下文
在 XState 中,context
是你在状态机 actor 中存储数据的方式。
context
属性在所有状态中都可用,用于存储与 actor 相关的数据。context
对象是不可变的,因此你不能直接修改它。相反,对于状态机逻辑,你可以使用 assign(...)
动作来更新 context
。
context
属性是 可选的;如果状态机只指定了 有限状态 而没有外部上下文数据,则可能不需要 context
。
import { createMachine, createActor } from 'xstate';
const feedbackMachine = createMachine({
// 使用上下文初始化状态机
context: {
feedback: 'Some feedback',
},
});
const feedbackActor = createActor(feedbackMachine);
feedbackActor.subscribe((state) => {
console.log(state.context.feedback);
});
feedbackActor.start();
// logs 'Some feedback'
初始上下文
在状态机配置的 context
属性中设置初始上下文:
import { createMachine } from 'xstate';
const feedbackMachine = createMachine({
context: {
feedback: '一些反馈',
rating: 5,
// 其他属性
},
});
你传递给 context
的对象将成为从该状态机创建的任何 actor 的初始 context
值。
惰性初始上下文
可以通过传递一个返回初始 context
值的函数来惰性地初始化上下文:
const feedbackMachine = createMachine({
context: () => ({
feedback: 'Some feedback',
createdAt: Date.now(),
}),
});
const feedbackActor = createActor(feedbackMachine).start();
console.log(feedbackActor.getSnapshot().context.createdAt);
// 记录当前时间戳
惰性初始上下文是针对每个 actor 评估的,因此每个 actor 都将拥有自己的 context
对象。
输入
你可以通过将 input
属性传递给 createActor(machine, { input })
函数,并在 context
函数的第一个参数中使用 input
属性,为状态机的初始 context
提供输入数据:
import { setup, createActor } from 'xstate';
const feedbackMachine = setup({
types: {
context: {} as {
feedback: string;
rating: number;
},
input: {} as {
defaultRating: number
}
}
}).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.
使用 assign(...)
更新上下文
在转换中使用 assign(...)
动作来更新上下文:
import { createMachine, assign, createActor } 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
你可以在 actor 设置的 types.context
属性中强类型化你的状态机 context
。
import { setup } from 'xstate';
const machine = setup({
types: {} as {
context: {
feedback: string;
rating: number;
};
}
}).createMachine({
// Initial context
context: {
feedback: '',
rating: 5,
},
entry: ({ context }) => {
context.feedback; // string
context.rating; // number
},
});
上下文速查表
使用下面的 XState 上下文速查表快速入门。
速查表:初始上下文
const machine = createMachine({
context: {
feedback: '',
},
});
速查表:惰性初始上下文
const machine = createMachine({
context: () => ({
feedback: '',
createdAt: Date.now(),
}),
});
速查表:使用 assign(...)
更新上下文
const machine = createMachine({
context: {
feedback: '',
},
on: {
'feedback.update': {
actions: assign({
feedback: ({ event }) => event.feedback,
}),
},
},
});
速查表:输入
import { setup, createActor } from 'xstate';
const feedbackMachine = setup({
types: {
context: {} as {
feedback: string;
rating: number;
},
input: {} as {
defaultRating: number
}
}
}).createMachine({
context: ({ input }) => ({
feedback: '',
rating: input.defaultRating,
}),
});
const feedbackActor = createActor(feedbackMachine, {
input: {
defaultRating: 5,
},
}).start();