question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Variables not updated when refetch with useQuery() + skip: true

See original GitHub issue

Recently our teams just migrated apollo-client from v2 to v3, and found out a behavior change:

In our codebase we call useQuery() with skip: true, updating the variables during rerender, and call the returned refetch() to fire the query, for example:

function Foo() {
  // we update `count` in other place and trigger variables change.
  const [count, setCount] = useState(0);
  const { refetch, data } = useQuery({
    skip: true,
    variables: { count },
  });

  // skip other code...
  
  // Fire refetch on user click button(just for example)
  return <button onClick={() => refetch()} />
}

We do useQuery() + skip: true + refetch because useLazyQuery() returns void instead of promise. We have used this workaround for a long time.

Then we found out that, in v3 (3.4.10), when refetch(), the request will not bring the latest variables but the initial variables. In above case, the count in variables will always be 0.

In v2, the variables will always be updated, which is the behavior we expected.

Related PR

The behavior change seems start from https://github.com/apollographql/apollo-client/pull/6752. It prevents network request when options update with skip: true, but it also prevents options update.

This comment shows that a portion of apollo-client users do use useQuery() + skip: true + refetch() as a substitution of useLazyQuery(). For us, this behaivor change is an implicit breaking change and cause unexpected bug during the migration from v2 -> v3(we spend one month discovering this issue after finishing v3 migration). I hope we can fix this behavior change so it would be less painful for people migrating to v3.

Intended outcome:

When call refetch() with useQuery() + skip: true, the query options should be updated.

Actual outcome:

When call refetch() with useQuery() + skip: true, the query options are not updated.

How to reproduce the issue:

codesandbox: https://codesandbox.io/s/recursing-goodall-mcd76

The request will fired when renderTimes > 3, Notice that the fired request will always bring outdated variables limit: 1 instead of updating limit with renderTimes.

Versions

System:
    OS: macOS 10.15.3
  Binaries:
    Node: 12.16.3 - ~/.nvm/versions/node/v12.16.3/bin/node
    Yarn: 1.22.15 - ~/.yvm/shim/yarn
    npm: 6.14.4 - ~/.nvm/versions/node/v12.16.3/bin/npm
  Browsers:
    Chrome: 94.0.4606.81
    Firefox: 89.0
    Safari: 13.0.5
  npmPackages:
    @apollo/client: ^3.4.10 => 3.4.10

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:14
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
chenesancommented, Nov 8, 2021

@brainkim Thanks for the response!

So looking at your repro on Code Sandbox, I’m wondering why the hook which calls setRenderTimes() does not have a dependency array?

Just rewrite the effect with setInterval, sorry for misleading 🙇 . Here I just want to demo that the renderTimes changes in each render and update the variables in query options, however the variables sent by refetch() is still initial 1(initial value of renderTimes), not renderTimes.

Also note that the refetch() function can take new variables.

Yes, this can resolve the problem. But, before migrate to v3 we don’t need to pass new variable and apollo-client can take the newest variables from options to refetch even though the query is skipped. After #6752 if we don’t pass new variables it will ignore the variables passed to skipped query instead, which is a breaking change I think? For this behavior change, we have to check if we call refetch without new variables all over our codebase 😢

Finally, I was wondering if you could try this in @apollo/client@beta? There’s been a significant refactoring of the React layer, and this problem might be fixed there.

Tried 3.5.0-beta.18 in codesandbox and still the same.

1reaction
chenesancommented, Jun 29, 2022

Tried 3.6.9 and looks good now! thanks @jpvajda

Read more comments on GitHub >

github_iconTop Results From Across the Web

Refetching queries in Apollo Client - Apollo GraphQL Docs
The client.refetchQueries method collects the TResult results returned by onQueryUpdated , defaulting to TResult = Promise<ApolloQueryResult<any>> if ...
Read more >
apollo graphql UI is not updating after refetch - Stack Overflow
I encountered a problem where the data from the useQuery hook was not updating after calling the refetch function.
Read more >
graphql-hooks - npm
refetch (options) : Function - useful when refetching the same query after a mutation; NOTE this presets skipCache=true & will bypass the options ......
Read more >
useQuery | Vue Apollo
none; all; ignore ... Only fetch from network if cached result is not available. ... Execute the query again, optionally with new variables....
Read more >
React Query FAQs - TkDodo's blog
4 // this is not how it works. 5 refetch({ id: 2 }). 6}})>Show Item 2</button>. Parameters or Variables are dependencies to your...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found