开启predictableActionArguments后,如何在XState中获取当前状态与事件源?
开启
predictableActionArguments: true时获取状态与事件源的方案 获取当前状态
开启该配置后,动作函数的参数会变为包含self属性的对象,self是状态机服务的实例,通过self.state可直接获取当前状态对象,进而提取状态值:
const myMachine = createMachine({ states: { // 其他状态... error: { entry: ({ context, event, self }) => { const currentStateValue = self.state.value; console.error(`Error in state '${currentStateValue}': ${event.type} - ${(event as any).data}`); } } } }, { predictableActionArguments: true });
获取事件源
由于meta参数被移除,原meta._event.origin无法直接访问,可通过以下两种方案解决:
1. 发送事件时显式传递源信息
在触发错误事件时,手动将事件来源(如当前状态、触发的Actor等)添加到事件对象的自定义属性中,比如origin:
// 在某个状态的动作中发送错误事件 send({ type: 'ERROR', data: new Error('Something went wrong'), origin: self.state.value // 传递当前状态作为来源 });
随后在error状态的entry动作中直接读取该属性:
entry: ({ event }) => { const eventOrigin = (event as any).origin; console.error(`Error origin: '${eventOrigin}'`); }
2. 利用状态机历史状态(适用于来源为前序状态的场景)
若事件来源是状态机的前序状态,可通过self.state.history获取历史状态信息,以此推断事件触发上下文:
entry: ({ self }) => { const previousState = self.state.history?.value; console.error(`Error triggered from previous state: '${previousState}'`); }
完整示例
const myMachine = createMachine({ initial: 'loading', states: { loading: { entry: ({ self }) => { // 模拟触发错误 setTimeout(() => { self.send({ type: 'ERROR', data: new Error('Failed to load data'), origin: 'loading' // 显式传递来源 }); }, 1000); }, on: { ERROR: 'error' } }, error: { entry: ({ context, event, self }) => { const currentState = self.state.value; const eventOrigin = (event as any).origin; const errorData = (event as any).data; console.error( `Error in state '${currentState}' (origin: '${eventOrigin}'): ` + `${event.type} - ${errorData.message}` ); console.error('Error stack:', errorData.stack); } } } }, { predictableActionArguments: true });
内容的提问来源于stack exchange,提问作者David Wolever
相关产品推荐
相关产品推荐

