polemius / recoil-persist

Package for recoil state manager to persist and rehydrate store
https://polemius.dev/recoil-persist/
MIT License
348 stars 40 forks source link

AsyncStorage implementation issue. #45

Open dezudas opened 2 years ago

dezudas commented 2 years ago

will it be possible to provide an example for AsyncStorage when I tried it says "Possible Unhandled Promise Rejection (id: 0): TypeError: Cannot read property 'hasOwnProperty' of null"

deargosep commented 2 years ago

same here

fervailanti commented 2 years ago

Same here, any solution?

fagerbua commented 2 years ago

You don't need to use this library to get simple persistence with Recoil and React Native. Just adapt the localForage example from the Recoil documentation, and you get (with TypeScript):

import {atom, AtomEffect, DefaultValue} from "recoil";

function persistAtom<T>(key: string): AtomEffect<T> {
  return ({setSelf, onSet}) => {
    setSelf(AsyncStorage.getItem(key).then(savedValue =>
      savedValue != null
        ? JSON.parse(savedValue)
        : new DefaultValue() // Abort initialization if no value was stored
    ));

    // Subscribe to state changes and persist them to localForage
    onSet((newValue, _, isReset) => {
      isReset
        ? AsyncStorage.removeItem(key)
        : AsyncStorage.setItem(key, JSON.stringify(newValue));
    });
  };
}

const myAtom =  atom({key: 'my-key', default: {}, effects_UNSTABLE: [persistAtom('my-async-storage-key')]})

Then wrap your RecoilRoot with a Suspense component:

      <React.Suspense fallback={<View><Text>Loading</Text></View>}>
        <RecoilRoot>
          {/* your app components */}
        </RecoilRoot>
      </React.Suspense>
cuzzlor commented 1 year ago

Despite the typings, it doesn't seem to support async getItem or setItem.

image

ipoogleduck commented 10 months ago

I had to adapt the code from @fagerbua cause I was getting blank screens. This worked better for me, copying the latest recoil documentation:

function persistAtom<T>(key: string): AtomEffect<T> {
    return ({ setSelf, onSet, trigger }) => {
        const loadPersisted = async () => {
            const savedValue = await AsyncStorage.getItem(key);

            if (savedValue != null) {
                setSelf(JSON.parse(savedValue));
            }
        };

        // Asynchronously set the persisted data
        if (trigger === 'get') {
            loadPersisted();
        }

        // Subscribe to state changes and persist them to localForage
        onSet((newValue, _, isReset) => {
            isReset
                ? AsyncStorage.removeItem(key)
                : AsyncStorage.setItem(key, JSON.stringify(newValue));
        })
    }
}

const myAtom =  atom({key: 'my-key', default: {}, effects_UNSTABLE: [persistAtom('my-async-storage-key')]})