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.

[3.3.0-rc.0] useQuery re-queries other useQuery hooks that share the same query doc

See original GitHub issue

Intended outcome:

Use case where an application uses the same component multiple times, i.e. A on-demand video carousel. That uses a useQuery hook and the same query document but has different query variables every time, i.e. categoryName. The application only queries the carousels that are in viewport with scroll listener/intersection observer, as the user scrolls a previously unseen carousel into viewport it is mounted and should run the query with its unique variables.

Actual outcome:

Every time a new query is expected to run i.e. Carousel enters viewport, it re-runs all previous queries that share the same query document.

How to reproduce the issue:

It is tricky to reproduce with our API as it is not public facing, however downgrading to @apollo/client@3.2.5 fixes the issue.

The resolver for the carousels returns a deterministic unique id (essentially a hash of the input variables) for the result set and there are no “merge” warnings in the console from Apollo like previous issues I have encountered with AC3+. We are not using any reactive variables.

The useQuery options always use:

{
  fetchPolicy: 'cache-and-network',
  errorPolicy: 'all'
}

Could there be some kind of link connected the observables?

Versions

System: OS: macOS 10.15.7 Binaries: Node: 13.7.0 - ~/.nvm/versions/node/v13.7.0/bin/node Yarn: 1.22.5 - ~/.yarn/bin/yarn npm: 6.13.6 - ~/.nvm/versions/node/v13.7.0/bin/npm Browsers: Chrome: 86.0.4240.193 Safari: 14.0

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
brendanmoorecommented, Nov 24, 2020

@benjamn Wow thanks for the response and for implementing the new behaviour! This is fantastic 🎉

1reaction
benjamncommented, Nov 18, 2020

@brendanmoore Ahh yes, I see what you mean now.

The cache result invalidation system invalidates at the level of individual fields, so queries that did not previously consume the modified fields will not be invalidated. However, in cases where the query document is the same between the two useQuery hooks, there’s a much better chance of overlap between (probably all of) their fields, which means writing the second useQuery result will almost always invalidate the first useQuery result, which causes a network fetch with cache-and-network. I agree that outcome seems unfortunate in many cases.

Now you’ve got me thinking: maybe the over-invalidation strategy only needs to be the default strategy, when you haven’t configured keyArgs for the field. Because the cache doesn’t “know” anything about the meaning of arbitrary arguments, by default it stores a separate field value for each unique combination of arguments. This keeps the field values safely separated by arguments, but the cache has no knowledge of how those values might be related, so it can’t be sure whether one field value should be invalidated when a field value with slightly different arguments gets modified. To play it safe, it invalidates all field values with the same name.

However, if you do configure keyArgs: ["categoryName"] explicitly for the field, perhaps we could respect that choice by invalidating only field values derived from the same key arguments, rather than invalidating all field values with the same field name. You’re telling the cache that differences in categoryName should correspond to totally separate field values, so perhaps we should invalidate them separately, too.

I tried a quick experiment where I removed the fieldNameFromStoreName normalization in two places, and I was somewhat surprised that only one test in our whole test suite failed, which is good news for the feasibility of this change. It might not happen until Apollo Client 3.4, but I’m coming around to the idea.

Read more comments on GitHub >

github_iconTop Results From Across the Web

The useQuery hook | Lift-off I: Basics | Apollo Odyssey
The useQuery hook is the primary API for executing queries in a React application. We run a query within a React component by...
Read more >
useHooks - Easy to understand React Hook recipes
We bring you easy to understand React Hook code recipes so you can learn how React hooks work and feel more comfortable writing...
Read more >
A comprehensive guide to GraphQL with Apollo Client in React
1.4 Queries with useQuery React Hooks. The new version of Apollo Client provides support for describing all query operations with the Hooks API....
Read more >
Spark SQL & DataFrames - Apache Spark
Integrated. Seamlessly mix SQL queries with Spark programs. Spark SQL lets you query structured data inside Spark programs, using either SQL or a...
Read more >
Custom useQuery and refetch - TinyHouse: A Fullstack React ...
In this lesson, we'll address how we'd like a query refetch be made when the deleteListing mutation is fired. We'll have our useQuery...
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