question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

atomWithStorage in React Native trouble using AsyncStorage

See original GitHub issue

Hi, not sure if I’ve got something configured wrong or what but it seems like setting up the atomWithStorage function is not working great for me in React Native. I started by defining a simple atom with storage and a default state:

export const appSettingsAtom = atomWithStorage<AppSettings>('@appSettings', {
  servers: [],
});

but whenever I try to set it I get this error: image

After scanning through the code for atomWithStorage it looks like there is no AsyncStorage implementation at all currently. Turns out I didn’t read the docs closely enough and had assumed that AsyncStorage support was built-in, but I guess it’s not. Doesn’t seem like I can pass AsyncStorage directly as the third param to atomWithStorage since it’s not type compatible, so I tried to implement my own Storage object (which I would prefer to do anyway so I can handle my own logging later):

export async function getItem(key: string): Promise<any | null> {
  try {
    const item = await AsyncStorage.getItem(key);
    return item ? JSON.parse(item) : null;
  } catch (e) {
    console.error(`getItem error (key: ${key})`, e);
    return null;
  }
}

export async function setItem(key: string, item: any): Promise<void> {
  try {
    await AsyncStorage.setItem(key, JSON.stringify(item));
  } catch (e) {
    console.error(`setItem error (key: ${key})`, e);
  }
}

export const atomStore = {
  getItem,
  setItem,
  delayInit: true,
}

…but now I get an error about the value of the atom being null: image

Ok, maybe that’s because my getItem function can return null if the key doesn’t exist, but that’s weird since that’s the default behavior for AsyncStorage. Alright, so now I re-implement getItem to also return the default value:

import { getItem, setItem } from '../storage/asyncstorage';

export const appSettingsAtom = atomWithStorage<AppSettings>('@appSettings', {
  servers: [],
}, {
  getItem: async () => {
    const item = await getItem('@appSettings');
    return item || { servers: [] };
  },
  setItem: setItem,
  delayInit: true,
});

And now it finally seems to work, but I have to tell it about my key and default value multiple times, which doesn’t feel great. I could wrap this up in another utility function on my end that provides these things, but I guess I’m left wondering is this the intended workflow here with AsyncStorage or am I missing a built-in utility somewhere that simplifies this?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
austinriedcommented, Jun 28, 2021

Seems good to me, maybe exporting the Storage<T> type then is something that will be better for a more fully-fledged jotai-storage package like you mentioned in the future.

1reaction
dai-shicommented, Jun 28, 2021

Check the latest code in the PR.

Now, it would allow you this:

const appSettingsAtom = atomWithStorage('@appSettings', appSettingsDefault, createJSONStorage(() => AsyncStorage))

Please git it a try.

Read more comments on GitHub >

github_iconTop Results From Across the Web

atomWithStorage trouble with AsyncStorage #780 - GitHub
I am trying to store error data with atomWithStorage in React Native. This is my atom. export const errorStorageAtom = atomWithStorage(' ...
Read more >
atomWithStorage - Jotai
The atomWithStorage function creates an atom with a value persisted in localStorage or sessionStorage for React or AsyncStorage for React Native.
Read more >
Problems with AsyncStorage in React Native - Stack Overflow
I am building my first React Native app. I am in the process of making the automatic login with AsyncStorage. I already got...
Read more >
docs/guides/react-native.mdx | jotai@v1.6.0 - Deno
First, create a storage item using the createJSONStorage function. This automatically stringifies and parses objects before writing to AsyncStorage. If you use ......
Read more >
Jotai: The Ultimate React State Management - 100ms
atomWithStorage is a special kind of atom that automatically syncs the value provided to it with localstorage or sessionStorage (Or AsyncStorage ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found