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

When there is a defaultOptions.watchQuery.fetchPolicy defined, useQuery doesn't return data when skip changes from true to false #9717

Closed
JoSuzuki opened this issue May 13, 2022 · 4 comments
Labels

Comments

@JoSuzuki
Copy link

Intended outcome:

When toggling the skip option from true to false in useQuery it returns data with content.

const client = new ApolloClient({
  uri: "https://48p1r2roz4.sse.codesandbox.io",
  cache: new InMemoryCache(),
  defaultOptions: {
    watchQuery: {
      fetchPolicy: "cache-and-network",
      nextFetchPolicy: (
        lastFetchPolicy,
        { reason, initialFetchPolicy, options }
      ) => {
        console.log(lastFetchPolicy, reason, initialFetchPolicy);

        if (reason === "variables-changed") {
          return initialFetchPolicy;
        }

        if (lastFetchPolicy === "cache-and-network") {
          return "cache-first";
        }
        return lastFetchPolicy;
      }
    }
  }
});

function ExchangeRates() {
  const [currency, setCurrency] = useState("USD");
  const [skip, setSkip] = useState(false);
  const { loading, error, data } = useQuery(exchangeRatesGql, {
    variables: {
      currency: currency
    },
    skip
  });

  return (
    <>
      <input value={currency} onChange={(e) => setCurrency(e.target.value)} />
      <button
        onClick={() => setSkip((prevSkip) => !prevSkip)}
      >{`toggle skip: ${skip}`}</button>
      {(data?.rates ?? []).map(({ currency, rate }) => (
        <div key={currency}>
          <p>
            {currency}: {rate}
          </p>
        </div>
      ))}
    </>
  );
}

Actual outcome:

After setting the option skip: true, the query is skipped forever, even if we update skip to false and change the query variables.

Not sure if it is related, but by logging what we receive on nextFetchPolicy the initialFetchPolicy and lastFetchPolicy are set as standby and not cache-and-network or cache-first which were the configured options in the client.

How to reproduce the issue:

  1. Define a defaultOptions.watchQuery.fetchPolicy when creating the ApolloClient
  2. Create a query with skip: false
  3. Update the state so that skip: true
  4. ✅ Data will return undefined as expected
  5. Update the state so that skip: false
  6. ❌ Data will still be undefined

I've created an reproduction example in codesandbox:

https://codesandbox.io/s/apollo-client-3-6-2-usequery-doesnt-return-data-when-skip-changes-from-true-to-false-vz14mp?file=/src/index.js

Versions

In the codesandbox

"@apollo/client": "3.6.2",
"graphql": "15.8.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-scripts": "5.0.0"

In my local reproduction

  System:
    OS: Linux 5.10 Ubuntu 20.04.4 LTS (Focal Fossa)
  Binaries:
    Node: 16.15.0 - ~/.nvm/versions/node/v16.15.0/bin/node
    Yarn: 1.22.4 - ~/Projects/QultureApp/node_modules/.bin/yarn
    npm: 8.5.5 - ~/.nvm/versions/node/v16.15.0/bin/npm
@benjamn
Copy link
Member

benjamn commented May 13, 2022

@JoSuzuki Thanks to your reproduction, I can say with some confidence this problem will be fixed in the next 3.6.x version, 3.6.4. The best way to try/test those changes right now is to run npm i @apollo/client@beta to get version 3.7.0-alpha.4 (still very similar to 3.6.x). Please let us know if that fixes the problem in your real project (or not)!

@JoSuzuki
Copy link
Author

In my real project, bumping to 3.7.0-alpha.4 seems to have solved the issue!

@Nedomas
Copy link

Nedomas commented May 22, 2022

I guess this is related somehow. I've done a lot of digging on fetchPolicy / skip / variables-changed on recent betas (3.7.0+) and it looks like there's some scenarios where skip is not honoured when variables change. I had to resort to wrapping useQuery with variables: opts.skip ? {} : opts.variables, to make sure that the client does not send queries that should be skipped. No recent beta fixes it and the bug has been here since 3.6+ as it does not happen with 3.5.

@jpvajda
Copy link
Contributor

jpvajda commented Jun 3, 2022

@Nedomas thanks for sharing that, I'm going to close this issue and we can collaborate on your problem in #9673

@jpvajda jpvajda closed this as completed Jun 3, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants