Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
LinusU opened this issue Jun 5, 2020 · 6 comments

Comments

@LinusU
Copy link

LinusU commented Jun 5, 2020

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 
@darkbasic
Copy link

I think this could be a duplicate of #6392

@LinusU
Copy link
Author

LinusU commented Jun 5, 2020

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 <grxy@users.noreply.github.com>
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(-)

@LinusU
Copy link
Author

LinusU commented Jun 5, 2020

@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 👍

@LinusU
Copy link
Author

LinusU commented Jun 5, 2020

ping @grxy, it seems like your commit c76804e maybe relied on some incorrect assumptions about isMounted, do you have any ideas on how we can fix this?

@benjamn
Copy link
Member

benjamn commented Jun 5, 2020

Heads up: we reverted #6216 for now in @apollo/client@3.0.0-rc.2 (just published).

@benjamn
Copy link
Member

benjamn commented Jun 23, 2020

Closing because I believe this is fixed. Thanks for reporting (and bisecting), @LinusU!

@benjamn benjamn closed this as completed Jun 23, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants