-
-
Notifications
You must be signed in to change notification settings - Fork 642
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
atomWithStorage in React Native trouble using AsyncStorage #568
Comments
Hi! It's nice to see someone try atomWithStorage with RN's AsyncStorage. const appSettingsAtom = atomWithStorage('@appSettings', {
servers: [],
}, {
getItem: (key) => AsyncStorage.getItem(key).then((str) => JSON.parse(str)),
setItem: (key, value) => AsyncStorage.setItem(key, JSON.stringify(value)),
delayInit: true,
}); I was hoping something like this would work. Would you please try it? |
Hey no problem, I'm switching from recoil in a prototype I'm working on currently and loving jotai so far, just got a little hung up on this part. Your code is close but it doesn't quite compile for me with typescript due to const appSettingsDefault = { servers: [] };
const appSettingsAtom = atomWithStorage('@appSettings', appSettingsDefault, {
getItem: (key) => AsyncStorage.getItem(key).then((str) => str ? JSON.parse(str) : appSettingsDefault),
setItem: (key, value) => AsyncStorage.setItem(key, JSON.stringify(value)),
delayInit: true,
}); |
Thanks for the suggestion. I made a small fix #569. My hope is to work this: const anyAsyncStorage = {
getItem: (key) => AsyncStorage.getItem(key).then((str) => JSON.parse(str || '')),
setItem: (key, value) => AsyncStorage.setItem(key, JSON.stringify(value)),
delayInit: true,
}
const appSettingsAtom = atomWithStorage('@appSettings', appSettingsDefault, anyAsyncStorage) Would you try the codesandbox build? |
Yep looks like PR build works for me with your example above, without it I get an unhandled promise rejection from
But after applying your change that is resolved. I wonder if there could be a simpler way of integrating AsyncStorage in the future though without having to write that boilerplate? If you'd be open to it, I may try my hand at an implementation that does something like take a peer dependency on AsyncStorage an implements it directly as the storage when |
Cool. Thanks for confirming. I'm not sure if those 5 lines is too much boilerplate, but my point is it's hard to fulfill everyone's need. I wouldn't recommend the default localStorage either. They come with That said, we are open for improvements for better developer experience. Hm, I might have a small idea to expose json storage creator, which might make your use case easier. Let me see. |
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. |
Gotcha, yeah we're going to have to deal with I've tried your example above and it works great, although in TS if I want to keep the generic type of I would suggest also that it might be good to export the |
Thanks for confirming. Would you say the PR is ready for merge?
Good point. However, I'm hesitant to export it at this point. It's not 100% fixed, and we should get more feedbacks before the fix. Furthermore, the name seems too general. |
Seems good to me, maybe exporting the |
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:but whenever I try to set it I get this error:
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 passAsyncStorage
directly as the third param toatomWithStorage
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):...but now I get an error about the value of the atom being null:
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-implementgetItem
to also return the default value: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?
The text was updated successfully, but these errors were encountered: