bikeshaving / crank

The Just JavaScript Framework
https://crank.js.org
MIT License
2.7k stars 75 forks source link

Call `cleanup()` functions even if component is unmounted #249

Closed brainkim closed 1 year ago

brainkim commented 1 year ago

While working on the homepage, the following function started causing "Component is unmounted" errors. Can you guess why?

async function *LoadingCreditCard() {
  await new Promise((r) => setTimeout(r, 1000));
  let count = 0;
  const interval = setInterval(() => {
    count++;
    this.refresh();
  }, 200);

  this.cleanup(() => clearInterval(interval));

  for ({} of this) {
    yield (
      <CreditCard
        number={"*".repeat(count) + "?".repeat(Math.max(0, 16 - count))}
        type={"Loading" + ".".repeat(count % 4)}
        owner="__ __"
        expiration="__/__"
      />
    );
  }
}

The reason is that the callback passed to this.cleanup() does not get called on already unmounted components, which can happen in this component when it unmounts before the setTimeout() promise settles.

Preliminary thoughts. The best way to fix this is to call the cleanup function immediately.

brainkim commented 1 year ago

Fixed in 0.5.3