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

Component scope infinite loop #74

Open
razvanip opened this issue Aug 8, 2024 · 7 comments
Open

Component scope infinite loop #74

razvanip opened this issue Aug 8, 2024 · 7 comments

Comments

@razvanip
Copy link

razvanip commented Aug 8, 2024

Bug

When using ComponentScope with an async jotai atom, the molecule is called indefinitely.

Reproduction

https://codesandbox.io/p/sandbox/bunshi-4ffckk?file=%2Fsrc%2FApp.js%3A9%2C27

Bunshi version

Tested on 2.1.4 and 2.1.5

@lazakrisz
Copy link

I think this is the same as #69, don't you think? 🤔

@razvanip
Copy link
Author

I think they are related but not the same since, suspending where the molecule is used does not solve the issue neither using a loadable atom.

@razvanip
Copy link
Author

razvanip commented Aug 23, 2024

@lazakrisz have u got the chanse to check this ?

@loganvolkers
Copy link
Member

@razvanip I'm getting a 404 for that sandbox. Is it protected or am I missing something?

@lazakrisz
Copy link

@lazakrisz have u got the chanse to check this ?

getting the same 404 error

@razvanip
Copy link
Author

razvanip commented Aug 28, 2024

https://codesandbox.io/p/sandbox/eloquent-buck-7ctd6h?file=%2FApp.tsx%3A39%2C1

// infinite loop due to ComponentScope and async atoms
const scope = getScope(ComponentScope);

@lazakrisz
Copy link

using the lodable atom instead of relying on the suspense boundary fixes the issue for me:

import { ComponentScope, createScope, molecule } from "bunshi";
import { use } from "bunshi/react";
import { atom } from "jotai/vanilla";
import { loadable } from "jotai/utils";

export const MultiplierMolecule = molecule(() => atom(0));

export const CountScope = createScope(0);
export const CountMolecule = molecule((mol, getScope) => {
  const initialCount = use(CountScope);

  // infinite loop due to ComponentScope and async atoms
  const scope = use(ComponentScope);

  console.log("COUNT MOLECULE", initialCount);
  const countAtom = atom(initialCount);

  const multiplierAtom = mol(MultiplierMolecule);

  const asyncAtom = atom(async (get) => {
    await new Promise((r) => setTimeout(r, 500));
    return get(countAtom) * get(multiplierAtom);
  });
  //using loadable here
  const valueAtom = loadable(asyncAtom);

  return {
    countAtom,
    valueAtom,
  };
});
import { useMolecule, ScopeProvider, createScope } from "bunshi/react";
import { useAtom, useAtomValue } from "jotai";
import React, { Suspense } from "react";
import { CountMolecule, CountScope, MultiplierMolecule } from "./molecules";

function Counter() {
  const { countAtom, valueAtom } = useMolecule(CountMolecule);
  const [count, setCount] = useAtom(countAtom);
  const value = useAtomValue(valueAtom);
  console.log("value", value);
  const increment = () => setCount((c) => c + 1);
  return (
    <div>
      <p>
        Clicks: {count} for total value {value.state}
      </p>
      <button onClick={increment}>Increment count</button>
    </div>
  );
}

function Multiplier() {
  const multiplierAtom = useMolecule(MultiplierMolecule);
  const [multiple, setMultiple] = useAtom(multiplierAtom);
  const increment = () => setMultiple((c) => c + 1);
  return (
    <div>
      <p>Multiplier: {multiple}</p>
      <button onClick={increment}>Increment multiplier</button>
    </div>
  );
}

export default function App() {
  return (
    <Suspense fallback={<div>loading</div>}>
      <div>
        <Multiplier />

        <ScopeProvider scope={CountScope} value={2}>
          <Suspense fallback={<div>Loading molecule</div>}>
            <Counter />
          </Suspense>
        </ScopeProvider>

        <Suspense fallback={<div>Loading molecule</div>}>
          <Counter />
        </Suspense>
      </div>
    </Suspense>
  );
}

so I'm guessing it is partially related to the issue that I've raised 🤔

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

No branches or pull requests

3 participants