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

using suspense mode with nullable ReturnType<fetcher> will cause a loop #517

Closed
mh-alahdadian opened this issue Jul 13, 2020 · 4 comments
Closed

Comments

@mh-alahdadian
Copy link
Contributor

mh-alahdadian commented Jul 13, 2020

Bug report

I am using swr to get a value which can be object or null
but when null received from server my component will stuck in a loop and will show loading and request many times to server

Expected Behavior

call getValue once and use it's falsy value as resolved data

Repro Steps / Code Example

https://codesandbox.io/s/swr-problem-with-suspense-with-nullable-fetcher-zfhc2

@huozhi
Copy link
Member

huozhi commented Jul 13, 2020

@mha15 you can provide your useSWR hook with option initialData and disable revalidateOnMount. Once swr detect there's any fallback value (initialData) or fulfilled value in cache. swr will stop revalidating in suspense mode. pick and to disable other options like revalidateOnFocus / revalidateOnReconnect if it's needed for you. this issue might be helpful

useSWR(key, fetcher, {
  initialData: /*<the default data you'd like to use>*/,
  revalidateOnMount: false,
}

and you might want to wrap your suspendable component with React.Suspense. I tried your example and modify it into the following pattern.

import * as React from "react";
import useSWR from "swr";

function getValue() {
  console.log("requested again");
  return Promise.resolve(null /* also for other falsy values like "" */);
}

function Main() {
  useSWR("nullable value", getValue, {
    suspense: true,
    initialData: "",
    revalidateOnMount: false
  });

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

export default function App() {
  return (
    <React.Suspense fallback={<span>fallback</span>}>
      <Main />
    </React.Suspense>
  );
}

@mh-alahdadian
Copy link
Contributor Author

@mha15 you can provide your useSWR hook with option initialData and disable revalidateOnMount. Once swr detect there's any fallback value (initialData) or fulfilled value in cache. swr will stop revalidating in suspense mode. pick and to disable other options like revalidateOnFocus / revalidateOnReconnect if it's needed for you. this issue might be helpful

I did try turning off all revalidates and it doesn't help and also this problem is only when falsy value returned from fetcher function and it will work just fine in other cases
and also I didn't want to set a defaultValue, why should I?

@muqg
Copy link

muqg commented Aug 7, 2020

I, too, experience such an issue. API call returns no content while data is not available, and JSON otherwise. Even if the initialData is explicitly set to null or an empty string (like @huozhi suggested), its invalidation still results in an endless loop as long as the API data is not available and the response content is empty.

React is at v16.13.1 and SWR is at v0.3.0 with the following options:

suspense: true,
revalidateOnReconnect: false,
revalidateOnFocus: false,
revalidateOnMount: false

@shuding
Copy link
Member

shuding commented Sep 20, 2020

Fixed in #524.

@shuding shuding closed this as completed Sep 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants