swr icon indicating copy to clipboard operation
swr copied to clipboard

`useSWRSubscription` suspends forever, never calls `subscribe` when `suspense` is `true`

Open steveluscher opened this issue 1 year ago • 1 comments
trafficstars

Bug report

Description / Observed Behavior

When configured with { suspense: true }, useSWRSubscription will render repeatedly, suspend indefinitely, and never call subscribe().

Expected Behavior

I would expect useSWRSubscription to suspend until the first time next() is called with data.

Repro Steps / Code Example

function subscribe(_key, { next }) {
  console.log('calling subscribe()')
  let counter = 0;
  const intervalId = setInterval(() => {
    next(null /* err */, counter++ /* data */);
  }, 1000);
  return () => {
    clearInterval(intervalId);
  };
}

function Counter() {
  console.log("rendering Counter");
  const { data: count } = useSWRSubscription("count", subscribe, {
    suspense: true,
  });
  return <span>{count}</span>;
}

Codesandbox repro (WARNING: infinite render loop)

Additional Context

SWR 2.2.5. Happens with strict mode and without. When suspense is false then subscribe() gets called. You can try that out with the Codesandbox repro above.

This is almost certainly because this invocation of useSWRNext() with no fetcher pulls an infinite loop when suspense is true

https://github.com/vercel/swr/blob/main/src/subscription/index.ts#L38

steveluscher avatar Jul 13 '24 00:07 steveluscher

cc/ @huozhi @shuding

steveluscher avatar Jul 13 '24 00:07 steveluscher