vercel / swr

React Hooks for Data Fetching
https://swr.vercel.app
MIT License
30.41k stars 1.21k forks source link

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

Open steveluscher opened 3 months ago

steveluscher commented 3 months ago

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 commented 3 months ago

cc/ @huozhi @shuding