如何在XState v5中从Promise Actor向父状态机发送事件?
XState v5 中 Promise Actor sendParent 未触发父状态机事件的排查方案
以下是几个常见的错误点和对应解决方法:
1. 父状态机未正确监听 Actor 发送的事件
父状态机在uploading状态中,需确保在invoke 配置的on字段中监听PROGRESS事件,而非直接放在状态的on节点下。
错误写法:
// machine.tsx const uploadMachine = createMachine({ states: { uploading: { invoke: { src: uploadActor, }, // 错误:此处的on不会监听invoke actor发送的事件 on: { PROGRESS: { actions: assign({ progress: (context, event) => event.value }) } } } } });
正确写法:
// machine.tsx const uploadMachine = createMachine({ states: { uploading: { invoke: { src: uploadActor, // 正确:在invoke的on中监听actor发送的事件 on: { PROGRESS: { actions: assign({ progress: (context, event) => event.value }) } } } } } });
2. sendParent 未传递标准事件结构
在fromPromise中使用sendParent时,必须传递包含type字段的标准XState事件对象。若仅传递字符串或非标准对象,父状态机可能无法识别。
示例:
// actors/upload.tsx import { fromPromise } from 'xstate'; const uploadActor = fromPromise(async ({ sendParent }) => { return new Promise((resolve) => { const uploadProgress = (percent: number) => { console.log('Sending progress to parent'); // 正确:传递带type字段的事件对象 sendParent({ type: 'PROGRESS', value: percent }); }; // 模拟上传进度 let progress = 0; const interval = setInterval(() => { progress += 10; uploadProgress(progress); if (progress >= 100) { clearInterval(interval); resolve('Upload complete'); } }, 500); }); });
3. 确认 Actor 未被意外终止
检查父状态机的uploading状态是否提前切换,导致Actor被终止。可在uploading状态添加entry/exit动作,验证状态生命周期是否符合预期:
uploading: { entry: () => console.log('Entered uploading state'), exit: () => console.log('Exited uploading state'), // ... 其他配置 }
4. 检查XState v5版本兼容性
部分早期XState v5版本中,fromPromise的sendParent存在兼容性问题,建议升级至最新稳定版。
内容的提问来源于stack exchange,提问作者bflemi3
相关产品推荐
相关产品推荐

