使用XState与React管理状态机时,TYPE事件中event.data为undefined导致报错的问题求助
我现在用XState结合React来管理状态机,在App组件里通过onChange处理器传递数据。控制台打印显示event.target.value是正常的字符串,但执行setResult的时候,event.data却是undefined。
当我在输入框输入内容时,会触发这个错误:
Cannot read properties of undefined (reading 'data')
TypeError: Cannot read properties of undefined (reading 'data')
at prompt
以下是我的代码,求各位帮忙看看哪里出问题了:
import { useMachine } from "@xstate/react"; import React from "react"; import { assign, createMachine } from "xstate"; const newMachine = createMachine( { id: "newMachine", initial: "idle", context: { result: "", prompt: "", }, on: { TYPE: { actions: ["setResult"], }, target: ".secondary", }, states: { idle: {}, secondary: { entry: "testPrint", }, }, }, { actions: { setResult: assign({ prompt: (context, event) => { console.log("Event: ", event); return event.data; }, }), testPrint: () => { console.log("TEST PRINT"); }, }, } ); export default function App() { const [current, send] = useMachine(newMachine); const { result, prompt } = current.context; return ( <div> Result: {result} <br /> State: {current.value} <br /> <input type="text" value={prompt} onChange={(event) => { console.log("Event onChange: ", event.target.value); send({ type: "TYPE", data: event.target.value }); }} /> </div> ); }
问题分析与解决方案
你遇到的问题主要是状态机配置的语法错误导致的,具体有两处:
事件转换的
target配置位置错误
你在on配置块里把target: ".secondary"写成了和TYPE事件同级的属性,这是完全错误的——XState的on配置是「事件类型」到「转换规则」的映射,target应该属于某个事件的转换规则,而不是on的顶级属性。这个错误会导致XState无法正确解析事件规则,甚至可能干扰事件对象的正常传递。状态路径错误
secondary是顶级状态(不是idle的子状态),所以状态路径应该用绝对路径"secondary",而不是相对路径".secondary"(相对路径仅用于指定当前状态的子状态)。
修改后的正确状态机配置
const newMachine = createMachine( { id: "newMachine", initial: "idle", context: { result: "", prompt: "", }, // 修正:将target移入TYPE事件的配置内,同时修正状态路径 on: { TYPE: { actions: ["setResult"], target: "secondary", }, }, states: { idle: {}, secondary: { entry: "testPrint", }, }, }, { actions: { setResult: assign({ prompt: (context, event) => { console.log("Event: ", event); return event.data; }, }), testPrint: () => { console.log("TEST PRINT"); }, }, } );
修改后,当你在输入框输入内容时,send({ type: "TYPE", data: event.target.value })发出的事件会被正确处理:event.data能正常拿到输入的值,状态也会切换到secondary并触发testPrint动作。
备注:内容来源于stack exchange,提问作者It's Just Me02

