Sorry for the bad title, didn't know how to summarise this any better.
We are using Apollo local state to store shopping carts in our app. After updating to 3.0.0-rc.0 from 3.0.0-beta.54 we had one of our useQuery no longer returning any data. By adding some logging, I've managed to get a somewhat clear picture of _what_ is happening, although I cannot understand _why_ or how to make it work:
Our component basically looks like this:
const GET_SHOPPING_CART_ENTRY = gql`
query GetShoppingCartEntry($restaurantId: ID!, $menuType: MenuType!, $entryId: ID!) {
shoppingCart(restaurantId: $restaurantId, menuType: $menuType) @client {
id
entry(id: $entryId) {
id
# ...
}
}
}
`
const EditProductDialog: React.FC<EditProductDialogProps> = ({ entryId, menuType, onDismiss, product, restaurantId }) => {
console.log('Calling useQuery')
const { data, loading, error } = useQuery<GetShoppingCartEntry, GetShoppingCartEntryVariables>(GET_SHOPPING_CART_ENTRY, { variables: { entryId, menuType, restaurantId } })
console.log('useQuery gave us', data, loading, error)
// ...
}
and our resolvers like this:
export const resolvers = {
ShoppingCart: {
entry: (_: FullShoppingCart, { id }: { id: string }, { cache, getCacheKey }: Context): ShoppingCartEntry | null => {
console.log('REQUEST FOR ENTRY')
const entry = cache.readFragment<FullShoppingCartEntry>({ fragment: FULL_SHOPPING_CART_ENTRY, id: getCacheKey({ __typename: 'ShoppingCartEntry', id }) })
console.log('entry', entry)
return entry
}
},
Query: {
shoppingCart: (_: {}, { restaurantId, menuType }: ShoppingCartLink, { cache, getCacheKey }: Context): FullShoppingCart => {
console.log('REQUEST FOR CART')
const cacheKey = getCacheKey({ __typename: 'ShoppingCart', id: `${restaurantId}-${menuType}` })
const current = cache.readFragment<FullShoppingCart>({ fragment: FULL_SHOPPING_CART, id: cacheKey })
console.log('current', current)
if (current != null) return current
const cart = {
__typename: 'ShoppingCart' as const,
id: `${restaurantId}-${menuType}`,
deliveryLocation: null,
deliveryTime: null,
discount: null,
idempotencyKey: nanoid(),
message: null,
tipPercentage: 0,
entries: []
}
cache.writeFragment<FullShoppingCart>({
fragment: FULL_SHOPPING_CART,
data: cart
})
cache.retain(cacheKey)
return cart
}
},
// ...
}
With that in place, this is what is being logged:
[Log] Calling useQuery (bundle.js, line 2179)
[Log] useQuery gave us – undefined - true - undefined (bundle.js, line 2190)
[Log] REQUEST FOR CART (bundle.js, line 12054)
[Log] current – {__typename: "ShoppingCart", id: "HykHQ0Qzlz-TakeAway", deliveryLocation: null, …} (bundle.js, line 12063)
{__typename: "ShoppingCart", id: "HykHQ0Qzlz-TakeAway", deliveryLocation: null, deliveryTime: null, discount: null, …}Object
[Log] REQUEST FOR ENTRY (bundle.js, line 12036)
[Log] entry – {__typename: "ShoppingCartEntry", id: "aB5UFyTfkkoKB288HtmH5", alternatives: Array, …} (bundle.js, line 12044)
{__typename: "ShoppingCartEntry", id: "aB5UFyTfkkoKB288HtmH5", alternatives: Array, count: 1, message: null, …}Object
The problem is that then nothing more happens, so the component never re-renders after getting the data from the resolvers.
Intended outcome:
I expected the useQuery call to run again and give me back the data, which would result in the following additional logs:
[Log] Calling useQuery (bundle.js, line 2179)
[Log] useQuery gave us – [...] - false - undefined (bundle.js, line 2190)
Actual outcome:
useQuery doesn't give me any data at all, and is just stuck in the "loading" state indefinitely...
But, if I make another modification to the cache while that component is still rendering, the useQuery resolves and give me back the data.
How to reproduce the issue:
I haven't been able to narrow this down more, working on it currently...
Versions
System:
OS: macOS 10.15.4
Binaries:
Node: 14.0.0 - /usr/local/bin/node
Yarn: 1.22.4 - ~/coding/loco/client-neue/node_modules/.bin/yarn
npm: 6.14.4 - /usr/local/bin/npm
Browsers:
Safari: 13.1
npmPackages:
@apollo/client: ^3.0.0-rc.1 => 3.0.0-rc.1
@apollo/link-context: ^2.0.0-beta.3 => 2.0.0-beta.3
apollo: ^2.26.0 => 2.26.0
I think this could be a duplicate of https://github.com/apollographql/apollo-client/issues/6392
So I did the only sane thing left and decided to use git bisect to see which commit broke it, here is the result:
$ git bisect start v3.0.0-rc.0 v3.0.0-beta.54
Bisecting: 4 revisions left to test after this (roughly 2 steps)
[045a0afa587e7697fe2ded7967614cf2e700a858] Fix typo in react/hoc.mdx (#6223)
$ npm run build
$ git bisect good
Bisecting: 2 revisions left to test after this (roughly 1 step)
[e572f4ce36c2729f9fc31a66b7439c6d9f7684fe] Allow setting new ApolloLink after ApolloClient instantiation (#6193)
$ npm run build
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[c76804eea2afcd3df4e01d5a8db3ae2c4c553aee] Avoid React StrictMode error when query resolves after unmount (#6216)
$ npm run build
$ git bisect bad
c76804eea2afcd3df4e01d5a8db3ae2c4c553aee is the first bad commit
commit c76804eea2afcd3df4e01d5a8db3ae2c4c553aee
Author: Grex <[email protected]>
Date: Tue Jun 2 09:45:10 2020 -0600
Avoid React StrictMode error when query resolves after unmount (#6216)
src/react/data/QueryData.ts | 6 ++--
src/react/hooks/__tests__/useQuery.test.tsx | 43 +++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 3 deletions(-)
@darkbasic thanks for the comment, subscribed to that one as well. Will continue to investigate here and see if I can submit a fix. If I manage that, we can see if that issue is also resolved 👍
ping @grxy, it seems like your commit https://github.com/apollographql/apollo-client/commit/c76804eea2afcd3df4e01d5a8db3ae2c4c553aee maybe relied on some incorrect assumptions about isMounted, do you have any ideas on how we can fix this?
Heads up: we reverted #6216 for now in @apollo/[email protected] (just published).
Closing because I believe this is fixed. Thanks for reporting (and bisecting), @LinusU!
Most helpful comment
Heads up: we reverted #6216 for now in
@apollo/[email protected](just published).