无法使用 xstate 恢复具有持久状态的状态机并做出反应
unable to restore state machine with persisted state using xstate and react
我正在尝试创建一个状态机,它可以在任何给定时间点保存机器的状态详细信息,然后在重新访问页面时使用保存的状态和上下文值恢复机器。 Xstate 文档提到了使用本地存储来持久化数据和再水化,但我无法这样做。我制作了一个沙盒 link 来尝试复制该问题。有人可以帮助或指导我做错什么吗?
提前致谢
Codesandbox link: https://codesandbox.io/s/green-snow-ortw6?file=/src/App.js
您必须在第一次调用 useMachine
时将持久状态传递给 useMachine
,不要忘记 useMachine
是一个闭包,这样它就可以工作,例如
import { useMachine } from "@xstate/react";
import { createMachine } from "xstate";
import { optionsConfig } from "./machine/machineDefinition";
import { machineConfig } from "./machine/machineDefinition";
import "./styles.css";
const machine = createMachine(machineConfig, optionsConfig);
export default function App() {
const [state, notifyMachine] = useMachine(machine, {
state: JSON.parse(localStorage.getItem("per_ste"))
});
const { context, value } = state;
const onNextClick = () => {
notifyMachine("NEXT");
};
const onPrevClick = () => {
notifyMachine("BACK");
};
const onEventAClick = () => {
notifyMachine("SEND_BUTTON_CLICKED", { data: "A" });
};
const onEventBClick = () => {
notifyMachine("SEND_BUTTON_CLICKED", { data: "B" });
};
const onLogContextButtonClick = () => {
console.log("CONTEXT:", context.eventTriggeredList);
};
const onLogStateButtonClick = () => {
console.log("CONTEXT:", value);
};
const onPersistClick = () => {
localStorage.setItem("per_ste", JSON.stringify(state));
};
const onRehydrateClick = () => {
const persistedState = localStorage.getItem("per_ste");
const parsedState = JSON.parse(persistedState);
setPersistedState(parsedState);
};
return (
<div className="App">
<h1>Step Machine</h1>
<h3>Start clicking to see some magic happen!</h3>
<h2>{`Current Step: ${context.currentStepIndex}`}</h2>
<div>
<button onClick={onNextClick}>NEXT</button>
<button onClick={onPrevClick}>PREV</button>
<button onClick={onEventAClick}>SEND EVENT A</button>
<button onClick={onEventBClick}>SEND EVENT B</button>
</div>
<br />
<div>
<button onClick={onLogContextButtonClick}>console Events</button>
<button onClick={onLogStateButtonClick}>console Current State</button>
</div>
<br />
<br />
<div>
<button onClick={onPersistClick}>PERSIST STATE</button>
<button onClick={onRehydrateClick}>REHYDRATE STATE</button>
</div>
</div>
);
}
我正在尝试创建一个状态机,它可以在任何给定时间点保存机器的状态详细信息,然后在重新访问页面时使用保存的状态和上下文值恢复机器。 Xstate 文档提到了使用本地存储来持久化数据和再水化,但我无法这样做。我制作了一个沙盒 link 来尝试复制该问题。有人可以帮助或指导我做错什么吗?
提前致谢
Codesandbox link: https://codesandbox.io/s/green-snow-ortw6?file=/src/App.js
您必须在第一次调用 useMachine
时将持久状态传递给 useMachine
,不要忘记 useMachine
是一个闭包,这样它就可以工作,例如
import { useMachine } from "@xstate/react";
import { createMachine } from "xstate";
import { optionsConfig } from "./machine/machineDefinition";
import { machineConfig } from "./machine/machineDefinition";
import "./styles.css";
const machine = createMachine(machineConfig, optionsConfig);
export default function App() {
const [state, notifyMachine] = useMachine(machine, {
state: JSON.parse(localStorage.getItem("per_ste"))
});
const { context, value } = state;
const onNextClick = () => {
notifyMachine("NEXT");
};
const onPrevClick = () => {
notifyMachine("BACK");
};
const onEventAClick = () => {
notifyMachine("SEND_BUTTON_CLICKED", { data: "A" });
};
const onEventBClick = () => {
notifyMachine("SEND_BUTTON_CLICKED", { data: "B" });
};
const onLogContextButtonClick = () => {
console.log("CONTEXT:", context.eventTriggeredList);
};
const onLogStateButtonClick = () => {
console.log("CONTEXT:", value);
};
const onPersistClick = () => {
localStorage.setItem("per_ste", JSON.stringify(state));
};
const onRehydrateClick = () => {
const persistedState = localStorage.getItem("per_ste");
const parsedState = JSON.parse(persistedState);
setPersistedState(parsedState);
};
return (
<div className="App">
<h1>Step Machine</h1>
<h3>Start clicking to see some magic happen!</h3>
<h2>{`Current Step: ${context.currentStepIndex}`}</h2>
<div>
<button onClick={onNextClick}>NEXT</button>
<button onClick={onPrevClick}>PREV</button>
<button onClick={onEventAClick}>SEND EVENT A</button>
<button onClick={onEventBClick}>SEND EVENT B</button>
</div>
<br />
<div>
<button onClick={onLogContextButtonClick}>console Events</button>
<button onClick={onLogStateButtonClick}>console Current State</button>
</div>
<br />
<br />
<div>
<button onClick={onPersistClick}>PERSIST STATE</button>
<button onClick={onRehydrateClick}>REHYDRATE STATE</button>
</div>
</div>
);
}