Apollo-client: Apollo local state: no re-render after resolver resolves with useQuery since 3.0.0-rc.0

Created on 5 Jun 2020  ·  6Comments  ·  Source: apollographql/apollo-client

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 
📟 regression 🛬 fixed-in-prerelease

Most helpful comment

Heads up: we reverted #6216 for now in @apollo/[email protected] (just published).

All 6 comments

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!

Was this page helpful?
0 / 5 - 0 ratings