-
-
Notifications
You must be signed in to change notification settings - Fork 645
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
feat(util): atomWithStorage #394
Conversation
Thanks for opening this up! I expect this is going to be a good one and thus taking time. Please bare with me. No ETA. |
src/utils/atomWithStorage.ts
Outdated
import type { SetStateAction } from '../core/types' | ||
|
||
export function atomWithStorage<Value>(key: string, initialValue: Value) { | ||
type Update = SetStateAction<Value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we accept function update? If so, L24-L26 should be implemented so. There's no magic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has to be:
(get, set, update: Update) => {
const newValue = typeof update === 'function' ? update(get(baseAtom)) : update
set(baseAtom, newValue)
window.localStorage.setItem(key, JSON.stringify(newValue))
}
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 77e45b6:
|
The WIP version looks actually good, and is worth a guide in docs. To make if a flexible util, we want to abstract the storage api. type Storage<Value> = {
getItem: (key: string) => Value | Promise<Value>
setItem: (key: string, newValue: Value) => void | Promise<void>
}
export function atomWithStorage<Value>(key: string, default: Value, getStorage?: () => Storage<Value>): PrimitiveAtom<Value> |
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/pmndrs/jotai/GqoydTYPnoGaaqDbFqTbv4X9sDWt |
@sandren Wow, I really loved this idea, Hope it gets released soon so I can use it in my new project. |
refactor abstract storage
add test for atomWithStorage
this is awesome, i haven't been able to test in RN environment, would there be a problem since getItem and setItem methods are async? |
@ghmeec We hoped this would support AsyncStorage, but not thoroughly tested. Would you give it a try? |
@dai-shi Awesome work here! I can confirm that atomWithStorage works on react-native if your atom is a string. It does appear to any JSON.stringify or JSON.parse. To get other types I had to dig through Jotai code until I found
For me, this is acceptable. I recommend maybe just adding it to the docs. |
Yeah, we don't have enough docs about |
Often, we need to store sensitive data like a token or basic authentication info for persistence, and storing such data plainly to localStorage seems less secure. Provision for a custom hook for encrypt/decrypt would be great to see |
You should be able to customize |
There are examples of how to add persistence to individual atoms in the docs, but I would like to create a robust
atomWithStorage
utility that covers most use cases, includinglocalStorage
orsessionStorage
for React as well asAsyncStorage
for React Native. Also note that the stored value is intentionally populated in theonMount
method rather than the baseatom()
initialization to supportatomWithStorage
usage in SSR contexts such as Next.js and Gatsby. The first commit is a work in progress.Progress