apollographql / apollographql/apollo-client
`fetchMore` race conditions when paginating after change to `useQuery` variables
- Dominant language
- TypeScript
- Stars
- 19.8k
- Forks
- 2.9k
- Avg merge
- 10h 17m
- Merged PRs (30d)
- 19
Description
### Issue Description
I have a strange issue where two successive calls to `fetchMore` will cause a bug _only if the query was changed once before_.
### Reproduction outline
- `fetchpolicy = "network-only"`
- paginating with a:
- [x] custom merge function
- [ ] custom read function
- query can be updated to include one extra field of the same object
- make three requests of 10 items each as soon as:
1. page loads (✅ no problem)
2. query updates (🐞 bug)
### Link to Reproduction
[Code sandbox](https://codesandbox.io/p/sandbox/graphql-apollo-pagination-public-lhrh24?layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clt5km8tt0006356h8jjgzsgr%2522%252C%2522sizes%2522%253A%255B70%252C30%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clt5km8tt0002356h4wmdflfa%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clt5km8tt0003356h55fwi6ch%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clt5km8tt0005356hmhz2a2ll%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B40.03706750894524%252C59.96293249105476%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clt5km8tt0002356h4wmdflfa%2522%253A%257B%2522id%2522%253A%2522clt5km8tt0002356h4wmdflfa%2522%252C%2522tabs%2522%253A%255B%255D%257D%252C%2522clt5km8tt0005356hmhz2a2ll%2522%253A%257B%2522id%2522%253A%2522clt5km8tt0005356hmhz2a2ll%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clt5km8tt0004356hdzuoj8uc%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522UNASSIGNED_PORT%2522%252C%2522port%2522%253A0%252C%2522path%2522%253A%2522%252F%2522%257D%255D%252C%2522activeTabId%2522%253A%2522clt5km8tt0004356hdzuoj8uc%2522%257D%252C%2522clt5km8tt0003356h55fwi6ch%2522%253A%257B%2522tabs%2522%253A%255B%255D%252C%2522id%2522%253A%2522clt5km8tt0003356h55fwi6ch%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D)
### Reproduction Steps
1. Press the "change query" button
**Result:** `data` returned from `useQuery` is stale, despite sequential calls to `fetchMore` (`fetchMore` updates not present).
### Example workarounds:
- Reduce the number of times `fetchMore` is called, (instead of two times just one time: change line 46 - change number `30` to `20`)
- In the merge function, if the query is changed (detect by: **`incoming` is first ten items**), then throw away the merged result and return only `incoming`
- In the original query, call more than one field. In the updated query, call fewer of those fields (seems to return cached result despite using `"network-only"`)
### `@apollo/client` version
3.9.5
Contributor guide
Research direction
Start with the linked CodeSandbox and reproduce the stale data after pressing “change query,” focusing on useQuery variables, fetchMore, and the custom merge function. Trace the pagination and cache behavior in the TypeScript client, then verify that successive fetchMore results remain current after the query changes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, typescript
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100