bunshi icon indicating copy to clipboard operation
bunshi copied to clipboard

Infinite execution when using jotai-apollo atoms

Open lazakrisz opened this issue 1 year ago • 3 comments

hello 👋 , first of amazing library thank you so much. as I was using the lib I noticed that whenever I create an atom (from jotai-apollo) within a molecule it keeps infinitely running (maybe related to dependencies?)

Couple other things that I have tried:

  • If i have a molecule that uses atoms from jotai-apollo, but I use it through an effect (jotai-effect) it works fine, and there is no infinite loading (see stackblitz)
  • I tried to memoize the atom, the getter function (first param of atomsWithQuery), I also tried to memoize the client getter (second param of atomsWithQuery) but none of these worked. If I memoized the molecule constructor function then I got an error saying that the dependencies have changes which is not supported.
  • also if you move the jotai-apollo atom outside of the molecule it also works fine

here is a stackblitz with the issue: https://stackblitz.com/edit/vitejs-vite-xaz7lw?file=src%2FApp.tsx if you uncomment the following part:

{/* <ScopeProvider scope={TestScope}>
        <InfiniteLoadingList />
  </ScopeProvider> */}

you should see continuous console logs from the molecule: image

if there is any way I can help please let me know (ex.: pr, tests etc...), although I'll probably require some assistance 🙏 .

lazakrisz avatar Jun 07 '24 14:06 lazakrisz

Thanks for the reproduction @lazakrisz and the cases where it fails and where it doesn't. That's really helpful!

This sounds like a classic integration testing problem. jotai-apollo and bunshi may both be operating the right way, but not when paired together.

image

I don't know what may be causing this.

The biggest help you could do is to add some test cases to ScopeProvider.test.tsx. If you can make it fail, then open a draft PR with the failing tests, and I can help figure out how to make them pass.

The Void scopes can be used to create unique molecules test might be a good foundation. It uses createLifecycleUtils to make sure a molecule isn't created more times than needed, which we want to be 1 but in the case you've created is Infinite.

loganvolkers avatar Jun 07 '24 17:06 loganvolkers

thank you @loganvolkers , will start to investigate this! 🔍

lazakrisz avatar Jun 08 '24 07:06 lazakrisz

Update as I was investigating this:

  • it seems the issue is related to Suspense boundaries and async atom data fetching behaviours and not references / memoization issues

by default each async atom in jotai uses Suspense in order to suspend until the data is available. (source: https://jotai.org/docs/utilities/async) If the Suspense Boundary is wrapping the component that is suspending while the promise is pending (see here: https://github.com/saasquatch/bunshi/blob/7594a71fba744b0519ae5a9cc91e005422aaefb1/src/react/ScopeProvider.test.tsx#L570) then all is good ✅ . However if the Suspense boundary is wrapping the entire application (in my Apps case) or in case of this test (see here: https://github.com/saasquatch/bunshi/blob/7594a71fba744b0519ae5a9cc91e005422aaefb1/src/react/ScopeProvider.test.tsx#L635) then the Suspense boundary is never unmounted (see here: https://github.com/saasquatch/bunshi/blob/7594a71fba744b0519ae5a9cc91e005422aaefb1/src/react/ScopeProvider.test.tsx#L684). Furthermore I have also forked and updated the Stackblitz to showcase this same behaviour: https://stackblitz.com/edit/vitejs-vite-eqmpey?file=src%2FApp.tsx I have added the new code within the LoadableList.

I also want to mention that there are currently two solutions to this problem from an application perspective:

  • use a Suspense boundary wrapping the component which is directly using the Promise atom (in my case and the Stackblitz's this is the atom that does the fetching using jotai-apollo)
  • Use a loadable from jotai/utils as mentioned in the jotai docs in order to not use Suspense while the Promise is pending.

I believe both are valid solutions, let me know what you think @loganvolkers 👍

lazakrisz avatar Jun 08 '24 09:06 lazakrisz