I was wondering if anyone's come up with some good/scalable patterns for hydrating state machines from a storage system that requires fetching asynchronously. Here's one thought I've come up with so far but I'm sure there's a more solid approach (I'm using react, but I'm sure general solutions would still help):
const machine = createMachine({})
const usePersistedMachine = (storageKey: string) => {
const [interpreter, setInterpreter] = useState<InterpreterFrom<
typeof machine
> | null>(null)
useEffect(() => {
const getState = async () => {
const state = await AsyncStorage.getItem(storageKey)
const interpreter = interpret(machine).start(
state ? JSON.parse(state) : machine.initialState,
)
setInterpreter(interpreter)
}
getState()
}, [storageKey])
return interpreter
}
const Component = () => {
const interpreter = usePersistedMachine('my-storage-key')
if (!interpreter) return null
return <Context.Provider value={interpreter}>{/* ... */ }</Context.Provider>
}
Follow up question: if I'm hydrating a machine that contains user data or something, what would be a good pattern/practice for re-checking if they're still logged in (i.e. access token hasn't expired)? That one seems a bit trickier. Only thing I've thought of for that (and it'd be highly dependent on the machine design) is to add this after creating the interpreter in getState above:
if (state) { // means I had something to hydrate
interpreter.send("check if authenticated")
}