#Hydrating a machine from AsyncStorage

1 messages · Page 1 of 1 (latest)

last wagon
#

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")
}
vast widget
#

You can pass the state directly to:

const [state, send] = useMachine(machine, {
  state: persistedState
})
#

Is it only rehydrated once? Or multiple times?