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

Infinite execution when using jotai-apollo atoms #69

Open
lazakrisz opened this issue Jun 7, 2024 · 3 comments
Open

Infinite execution when using jotai-apollo atoms #69

lazakrisz opened this issue Jun 7, 2024 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@lazakrisz
Copy link

lazakrisz commented Jun 7, 2024

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 🙏 .

@loganvolkers loganvolkers self-assigned this Jun 7, 2024
@loganvolkers loganvolkers added the bug Something isn't working label Jun 7, 2024
@loganvolkers
Copy link
Member

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.

@lazakrisz
Copy link
Author

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

@lazakrisz
Copy link
Author

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:

<Suspense fallback="Loading...">{children}</Suspense>
) 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:
<Suspense fallback="Loading...">
) then the Suspense boundary is never unmounted (see here:
await waitForElementToBeRemoved(() => screen.getByText("Loading..."));
).
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 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

2 participants