-
-
Notifications
You must be signed in to change notification settings - Fork 581
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
Writeable Atom with derived default value #352
Comments
Yeah, this use case is not well covered in the current api/docs. We did something similar in So, what we could do is to use three atoms. const defaultValueAtom = atom(async (get) => "some default")
const overwrittenValueAtom = atom(null)
const valueAtom = atom(
(get) => get(overwrittenValueAtom) || get(defaultValueAtom),
(_get, set, action) => set(overwrittenValueAtom, action)
) |
OK but how do I use that in my code then? [value, setValue] = atom(valueAtom) Does that really update the value or do I need 2 variables? One for reading, one for writing? |
This looks fine. |
OK that works. Thank you! The bigger question is: Os this considered a bug/unwanted behavior? I feel like that use case is quite common. |
The current behavior is correct, I'd say. I don't think we can support this in core, because we want to keep it minimal, and there's no nice way to add a feature in the current minimal api. So, the three atom solution is a valid approach currently. |
Actually, it might be possible to implement it with just one atom, using some undocumented properties. |
OK it seems like I don't get this to work with const familyStoreDefaultFalse = atomFamily<string, boolean>(() => false)
export const selectedLanguages = atomFamily<string, boolean, boolean>(
(languageId) => (get) => get(familyStoreDefaultFalse(`language-${languageId}`)) || get(defaultLanguageIDs).includes(languageId),
(languageId) => (_get, set, value) => set(familyStoreDefaultFalse(`language-${languageId}`), value),
)
const defaultLanguageIDs = atom<Array<string>>(["en"]) The selection works for all languages except for English (the default language). The setter of the |
I'm not sure if I fully understand the weird behavior described. Does it only happen with the default thing? const familyStoreDefaultFalse = atomFamily<string, boolean>(() => false)
export const selectedLanguages = atomFamily<string, boolean, boolean>(
(languageId) => (get) => get(familyStoreDefaultFalse(`language-${languageId}`)) || languageId === 'en',
(languageId) => (_get, set, value) => set(familyStoreDefaultFalse(`language-${languageId}`), value),
) I mean, does this reproduce the issue, or not? |
Okay, I guess this should fix it. const familyStoreDefaultFalse = atomFamily<string, boolean | null>(() => null)
export const selectedLanguages = atomFamily<string, boolean, boolean>(
(languageId) => (get) => get(familyStoreDefaultFalse(`language-${languageId}`)) ?? languageId === 'en',
(languageId) => (_get, set, value) => set(familyStoreDefaultFalse(`language-${languageId}`), value),
) |
Thank you. Now I can select and deselect English but it is NOT enabled by default. |
Did you change the default to |
Oh sorry, didn't see. Now it works. Thank you so much! |
I just recently went through a refactoring from recoil. Everything was pretty straightforward but one use case I couldn't build in jotai.
I have a list of countries I can fetch from the backend:
I built a defaultCountry atom based on this fetch
And now I have a
selectedCountry
atom which I want to initialize with the default country. But everything I tried resulted either in a type error or a readable only atom:I think the async fetch is not super relevant, because when I change my defaultCoutry atom to this, I'll run in the same problem:
So is there a way to build a writeable atom that I can initialize with a derived atom value?
The text was updated successfully, but these errors were encountered: