React+XState项目:无法从Editor子组件更新bookmarkMachine上下文
问题
我正在使用React和XState开发一款网站构建器应用。父组件<SkinsController>(代码中写为SkiController)使用状态机bookmarkMachine管理书签状态,子组件<Editor>有自己的状态机editorMachine负责编辑书签属性。
当用户在<Editor>中保存修改时,我希望向bookmarkMachine发送事件,创建带有更新属性的新书签,但bookmarkMachine的上下文并未更新,也没有报错信息。
以下是简化代码:
import { assign, createMachine } from "xstate"; export const bookmarkMachine = createMachine({ id: "bookmark", initial: "idle", context: { bookmarks: [], }, states: { idle: { on: { CREATE_BOOKMARK: { actions: assign((context, event) => { const newBookmark = { id: event.id, inputValue: event.inputValue, hState: event.hState, satState: event.satState, liState: event.liState, imageURL: event.imageURL, }; context.bookmarks.push(newBookmark); }), }, }, }, }, }); import React, { useState } from "react"; import Editor from "./Editor"; import { useMachine } from "@xstate/react"; import { bookmarkMachine } from "../machines/bookmarkMachine"; export default function SkiController() { const [component, setComponent] = useState(null); const [state, send] = useMachine(bookmarkMachine); const handleClick = (componentNumber) => { setComponent(componentNumber); }; return ( <div className="sController"> <div className="leftContainer"> {component === 1 && <Editor sendBookmarks={send} />} </div> </div> ); } import React from "react"; import { useMachine } from "@xstate/react"; import Rename from "./Rename"; import { editorMachine } from "../machines/editorMachine"; const Editor = ({ sendBookmarks }) => { const [state, send] = useMachine(editorMachine); const handleOpenRename = () => send("OPEN_RENAME"); const handleCloseRename = () => send("CLOSE_RENAME"); const handleSaveName = async (newName) => { send({ type: "SAVE_NAME", value: newName }); sendBookmarks({ type: "CREATE_BOOKMARK", id: newName, inputValue: newName, hState: state.context.hState, satState: state.context.satState, liState: state.context.liState, }); }; return ( <div className="Editor draggable"> <button onClick={handleOpenRename}>Rename</button> <Rename isOpen={state.matches("renaming")} onClose={handleCloseRename} onSave={handleSaveName} /> </div> ); }; export default Editor;
解决方案
- 保持上下文不可变性:XState依赖不可变更新来追踪上下文变化,你当前直接用
context.bookmarks.push(newBookmark)修改原数组,XState无法识别这个变化。需要返回一个新的数组对象:
actions: assign((context, event) => { const newBookmark = { id: event.id, inputValue: event.inputValue, hState: event.hState, satState: event.satState, liState: event.liState, imageURL: event.imageURL, }; // 返回新的上下文对象,包含新的书签数组 return { bookmarks: [...context.bookmarks, newBookmark] }; }),
补全事件参数:发送
CREATE_BOOKMARK事件时缺少imageURL参数,虽然不会直接导致上下文不更新,但可能引发后续逻辑问题,建议补充该参数或者根据业务需求调整newBookmark的字段定义。验证事件接收状态:可以在
SkiController中打印当前书签列表,确认事件是否被正确接收和处理:
// 在SkiController组件内添加 console.log('当前书签:', state.context.bookmarks);
内容的提问来源于stack exchange,提问作者SUMAN
相关产品推荐
相关产品推荐

