I am trying to create a state machine which can persist the machine's state details at any given point in time and then restore the machine with the persisted state and context values on revisiting the page. The Xstate docs mention about persisting data and rehydration using the local storage but I am unable to do so. I have made a sandbox link to try and replicate the issue. Can someone help or guide me on what I may be doing wrong?
Thanks in advance
Codesandbox link: https://codesandbox.io/s/green-snow-ortw6?file=/src/App.js
You must pass the persisted state the first time that you invoke to useMachine
, do not forget that useMachine
is a closure, in that way it will work, for instance
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>
);
}