jotai: atomWithProxy triggers infinite loop

When using atomWithProxy merely referencing any value from the state will cause an infinite loop. I created a minimal reproduction of the bug: https://codesandbox.io/s/jotaivaltio-infinite-loop-yphdz?file=/src/App.js

It has a proxy atom and it uses it like so: const [atomState] = useAtom(proxyAtom);

If you just print out something like JSON.stringify(atomState) everything is great, but the moment you do a simple change to JSON.stringify(atomState.someNestedKey) everything freezes in an infinite loop (even though the key exists and prints out successfully without being referenced directly.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (16 by maintainers)

Most upvoted comments

Would you update valtio v1.1.3 in devDependencies in #625 and if it passes the test?

I think that this issue can be closed (infinite refresh bug fixed) and the types can be tracked in the PR, what do you think @dai-shi ?

https://github.com/pmndrs/valtio/pull/202 is merged and v1.1.3 is published.

The above is fixed in the following PR over at valtio and the test now passes: https://github.com/pmndrs/valtio/pull/202

@dai-shi I’d love it if you took a look 😃

So, as far as I understand the following happens to cause the infinite loop:

  1. atomWithProxy creates a snapshot of the proxy
  2. The following logic executes and sets the prop to a getter that throws a promise: https://github.com/pmndrs/valtio/blob/master/src/vanilla.ts#L101-L110
  3. The promise resolves
  4. However, react instantly tries to render, hits the getter, gets an already resolved promise suspends for 0 milliseconds, re-renders, hits the getter, gets an already resolved promise, suspends for 0 milliseconds e.t.c
  5. It never actually manages to get another version of the snapshot

Alright, I’m giving it a stab now. Let’s see if anything useful comes out of it 😀