Skip to content
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

Cann't access atomWithStorage value in spa initial #2240

Closed
1 of 2 tasks
Innei opened this issue Nov 7, 2023 · 14 comments · Fixed by #2391
Closed
1 of 2 tasks

Cann't access atomWithStorage value in spa initial #2240

Innei opened this issue Nov 7, 2023 · 14 comments · Fixed by #2391

Comments

@Innei
Copy link

Innei commented Nov 7, 2023

Summary

When I use atomWithStorage, the storage already has this value present, but when I use jotaiStore.get(atom) I only get the initialValue.

This is a spa scenario, not an ssr scenario. When atomWithStorage is executed, globally window exists.

import { createStore } from "jotai/vanilla";
import { atomWithStorage } from 'jotai/vanilla/utils'

if(!localStorage.getItem('theme')) {
  localStorage.setItem('theme', 'light') // set localstorage key value if not exist
}

const jotaiStore  = createStore()

const themeAtom = atomWithStorage('theme', undefined, window.localStorage, {
  // unstable_getOnInit: true         // this default value is `false`
})

const v = jotaiStore.get(themeAtom)

console.log(v)      // v undefined

But if I set unstable_getOnInit to true, it can get the correct value.

Link to reproduction

https://codesandbox.io/s/serverless-thunder-s3gddk?file=/src/index.mjs

Check List

Please do not ask questions in issues.

  • I've already opened a discussion before opening this issue, or already discussed in other media.

Please include a minimal reproduction.

@jiangmaniu
Copy link

The same problem is that the value of storage cannot be obtained at the time of initialization.

@Innei
Copy link
Author

Innei commented Nov 7, 2023

The same problem is that the value of storage cannot be obtained at the time of initialization.

The current solution is to use unstable_getOnInit: true. I think getOnInit should be a reasonable behavior in non-ssr scenarios.

@dai-shi
Copy link
Member

dai-shi commented Nov 7, 2023

It's our design choice to have getOnInit false by default.

@dai-shi dai-shi closed this as completed Nov 7, 2023
@dai-shi
Copy link
Member

dai-shi commented Nov 7, 2023

That said, we should change unstable_getOnInit to getOnInit some time soon.

So, thanks for the feedback. Wish to get more feedback on it. How do you like the name getOnInit?

@Innei
Copy link
Author

Innei commented Nov 10, 2023

That said, we should change unstable_getOnInit to getOnInit some time soon.

So, thanks for the feedback. Wish to get more feedback on it. How do you like the name getOnInit?

Sounds great

@ViktorQvarfordt
Copy link

After a lot of confusion I ended up here. I would prefer if the default was true. At least I would expect this to be clearly documented an not hidden. In the docs no default is described. Cheers!

@dai-shi
Copy link
Member

dai-shi commented Dec 27, 2023

It's intentionally false by default. Otherwise, more people would get confused. (which was the case in v1).

Would you mind opening a PR to improve the docs?

@jaens
Copy link

jaens commented Jan 26, 2024

I just spent an hour debugging this exact issue - I have a very normal SPA which uses localStorage to store an auth token, migrated it to use atomWithStorage thinking it would be a drop-in, and suddenly the first render of a component always reads the uninitialized value for some reason (which causes the component to throw an exception, since it needs it to start fetching data...).

This unintuitive behaviour is not even really documented anywhere... truly a terrible first experience with Jotai.

@dai-shi could you at least please explain why getOnInit is not the default for storage atoms? "more people would get confused?" Confused about what? I am pretty confused about the way it is right now... How is reading an uninitialized value, but only on the first render anything besides confusing?

I think there are no storage items in the entire app which would be usable with getOnInit: false...

Reading between the lines, this seems to be about SSR somehow - but the majority of React apps do not even use SSR, as far as I see.

Seems to me that the API is fundamentally broken if the default is only usable in SSR and unusable in SPA (or vice versa, if the default would be switched to true). Perhaps splitting the API behaviour for these two very different use cases would lead to less confusion...

@ViktorQvarfordt
Copy link

Thank you for sharing. I share your frustration.

I believe the reason is to make it work well with hydration for SSR. But I view that as an opt-in, not the other way around. It would make sense for me if the defaults were tuned for code running in browsers. Most of my projects are SPAs without SSR (bacause content is behind login).

@dai-shi
Copy link
Member

dai-shi commented Jan 27, 2024

could you at least please explain why getOnInit is not the default for storage atoms?

It was the default behavior in v1 and we received many issues reported. It makes more sense to render initial value first and update with storage value next, and gives less trouble. Which is default can be controversial, but we've been there and done that.

@henrikvilhelmberglund
Copy link
Contributor

Was a bit confused by this too, it could be mentioned in the docs that the default is false.

@dai-shi
Copy link
Member

dai-shi commented Feb 6, 2024

Thanks for the feedback! Can you please open a PR to avoid such confusion?

@zhylmzr
Copy link

zhylmzr commented Feb 16, 2024

I'm a jotai newbie, while checking the official example, I found that the persistent state theme blink when refreshing the page (in my local editing environment. It doesn't blink in the playground), by printing I realized that it's because it doesn't get the initial value. But I found that in v1 version it will get the initial value, here is an example using v1: https://codesandbox.io/p/sandbox/brave-mountain-wv2zrt

Screenshot

PixPin_2024-02-16_21-19-45

@dai-shi
Copy link
Member

dai-shi commented Feb 16, 2024

See #2391

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants