Infinite re-render with async atomWithStorage and React 19 #2931
Replies: 5 comments 7 replies
-
Thanks for reporting. We should investigate this. To isolate the problem, what we want first is:
I would try when I have time, but if anyone is interested, feel free! |
Beta Was this translation helpful? Give feedback.
-
@dai-shi here is a smaller repro without using atomWithStorage, the issue is a combination of using |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
As StrictMode in React 19 remounts atoms, we need to return stable promises. Would it possible for you to do something like this? let storedValue = 0
let cachedPromise:
| [typeof storedValue, Promise<typeof storedValue>]
| null = null
const counterAtom = atomWithStorage('counter', 0, {
getItem(_key: string, _initialValue: number) {
if (cachedPromise && cachedPromise[0] === storedValue) {
return cachedPromise[1]
}
const promise = Promise.resolve(storedValue)
cachedPromise = [storedValue, promise]
return promise
},
async setItem(_key, newValue) {
storedValue = await new Promise((resolve) => resolve(newValue))
},
async removeItem() {},
}) |
Beta Was this translation helpful? Give feedback.
-
Seems like its also related to #2848 |
Beta Was this translation helpful? Give feedback.
-
Bug Description
I'm using the latest version of jotai alongside React 19. I have the following atom defined:
In absence of any calls to setting the atom, my expectation would be that this would only trigger two renders: one before the promise is resolved, rendering the suspense fallback, and once once the promise is resolved, rendering the tree. Instead I'm getting an infinite loop of going back and forth between fallback and suspense tree.
Repro showcasing the issue in 19.0.0: https://stackblitz.com/edit/vitejs-vite-z4b5kyy1?file=src%2FApp.tsx
This worked in React 18.3.1: https://stackblitz.com/edit/vitejs-vite-vhskxk28?file=package.json,src%2FApp.tsx
Reproduction Link
https://stackblitz.com/edit/vitejs-vite-z4b5kyy1?file=src%2FApp.tsx
Beta Was this translation helpful? Give feedback.
All reactions