SolidJSS
SolidJS•3y ago•
1 reply
Song

how to`createStore` and using `createEffect` to persist without warning

I want to create a function to persist the store to the localstorage, everything works, but it warns that computations created outside a createRoot or render will never be disposed. I have tried to move
createEffect
outside onMounted, but it even warn twice. Additionally, moving onMounted inside provider makes persist break. No help using ChatGPT🄲. Does anyone know how to solve it?
here is my code
export function persistStore< T extends object = {}, R extends ActionReturn = {}>(
  name: string,
  options: StoreOption<T, R>,
): [provider: ParentComponent, useStore: () => BaseStore<T, R>] {
  const { action, state, persist: persistOption } = options
  const initalState = typeof state === 'function' ? state() : state
  const [store, setStore] = createStore<T>(initalState, { name })

  const ctxData = { store, ...action(setStore) }
  const ctx = createContext(ctxData, { name: `ctx_${name}` })
  const option = normalizePersistOption(name, persistOption)
  onMount(() => {
    if (!option) {
      return
    }
    const { debug, key, serializer: { deserialize, serialize }, storage } = option
    const stored = storage.getItem(key)
    try {
      if (stored) {
        setStore(deserialize(stored))
        debug && console.log(`[$store - ${key}]: read from persisted, value: ${stored}`)
      } else {
        storage.setItem(option.key, serialize(store))
        debug && console.log(`[$store - ${key}]: no persisted data, initialize`)
      }
    } catch (e) {
      debug && console.error(`[$store - ${key}]: ${e}`)
    }
    createEffect(on(() => deepTrack(store), () => {
      debug && console.log(`[$store - ${key}]: update to ${JSON.stringify(store)}`)
      storage.setItem(option.key, serialize(unwrap(store)))
    }))
  })
  return [
    (props: ParentProps): JSX.Element =>
      createComponent(ctx.Provider, {
        value: ctxData,
        get children() {
          return props.children
        },
      }),
    () => useContext(ctx),
  ]
}
Was this page helpful?