Context
基本概念
Context 就是状态机里的“数据仓库”
Context 是所有 state 共用的
Context 是 只读的(不可直接修改)
不是每个 state 有一份,而是 整个状态机一份
ts
import { createMachine, createActor } 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'初始化 context
lazy Initial context
context支持使用函数,每个 actor 都会拥有自己独立的 context 对象。
ts
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传入context
你可以在创建 actor 时,通过 createActor(machine, { input }) 传入 input 数据,并在 context 函数中从第一个参数里读取 input:
ts
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修改context
在状态转换中,使用 assign(...) action 来更新 context:
ts
assign(Object)Object的key是context的key
直接值
value是直接值
ts
assign({
feedback: 'hello',
})函数
value是函数,这个函数接收event,event是传入send的事件对象EventObject
ts
send({
type: 'SUBMIT',
feedback: '很好用',
})ts
assign({
feedback: ({ event }) => {
// event 就是:
// { type: 'SUBMIT', feedback: '很好用' }
return event.feedback
},
})ts
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'TS
在setup中可以声明context的类型
ts
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
},
});