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.

useMutation updates cache but does not re-render components querying same object

See original GitHub issue

Intended outcome:

  • I am querying for one object (Object A) and checking for the existence of one of its fields (Object B) in a component using useQuery (Component A).
  • In a separate component (Component B), I am using useMutation to create Object B. In the payload, I am returning Object A, this time with a non-null Object B.
  • Component A should re-render since Object A updated in the cache and its Object B field is now not null
  • However the original component using useQuery did not re-render, period.

Actual outcome:

  • Component A does not re-render.
  • Strangely, with the apollo chrome plugin I can confirm that the cache did update

Some screenshots w/ info redacted. Object A is listing and Object B (the object being created) is latestValidPropertyInspection. The initial query: Screen Shot 2020-02-18 at 5 39 42 PM The mutation running and returning the new objects w/ non-null latestValidPropertyInspection: Screen Shot 2020-02-18 at 5 39 57 PM apollo chrome extension showing the cache updated after the mutation ran: Screen Shot 2020-02-18 at 5 40 22 PM

query:

  const result = useQuery({
    query: listingById,
    options: { variables: { id: currentListing.id } },
  });

mutation:

const [requestInspection, result] = useMutation(mutation: requestInspectionMutation);

How to reproduce the issue: Query for a single object in one component, with a field being another object but that is returning null. In another component, mutate to create said object, but return the parent (the original single object). You should find that the component did not render.

Versions


  System:
    OS: Linux 4.19 Debian GNU/Linux 8 (jessie) 8 (jessie)
  Binaries:
    Node: 10.11.0 - /usr/local/bin/node
    Yarn: 1.9.4 - /usr/local/bin/yarn
    npm: 6.4.1 - /usr/local/bin/npm
  npmPackages:
    @apollo/react-hooks: ^3.1.3 => 3.1.3
    apollo-cache-inmemory: ^1.6.3 => 1.6.3
    apollo-client: ^2.6.4 => 2.6.4
    apollo-link: ^1.2.13 => 1.2.13
    apollo-link-error: ^1.1.12 => 1.1.12
    apollo-link-retry: ^2.2.15 => 2.2.15
    apollo-link-state: ^0.4.2 => 0.4.2
    apollo-upload-client: ^11.0.0 => 11.0.0
    react-apollo: ^3.1.3 => 3.1.3

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:35
  • Comments:42 (5 by maintainers)

github_iconTop GitHub Comments

14reactions
fromicommented, Feb 23, 2021

I have a similar problem too. When the cache is modified, useQuery hook causes a rerender UNLESS the modified object in the cache is something that was not referenced the first time useQuery rendered. Here is my concrete example:

type Me {
  matchmakings: [Matchmaking!]!
  ...
}
type Matchmaking {
  joined: DateTime
 ...
}

Now I have a component that do useQuery to fetch “me”, and the matchmakings, in a single query.

  1. Case number 1: the component is rendered only after “me” has already been queried and is in the cache: {me && <MyComponent/>} => In that case, when I do cache.modify to change one of the matchmaking.joined date, the component rerenders (no bug).

  2. Case number 2: the component is rendered before “me” is in the cache. => first time the component renders, “me” is null (loading from backend) => later on, when I do cache.modify to change one of the matchmaking.joined date referred to by the “Me” object that was fetched meanwhile, the component is not rerendered

It is obviously a bug: the only difference between producing it or not is making sure useQuery hook will load from the cache from the first time. Otherwise, there is no update when I change an object in the cache that was not referenced from the start.

To fix the bug, “useQuery” should update properly all the cache references which are listened too to trigger a refresh.

10reactions
simonasdevcommented, Oct 7, 2021

I’ve also noticed what @dan-cooke said. useQuery hook returns stale data, even though cache is updated correctly. Actually the component calling useQuery won’t even re-render, if the mutation call is not at the same component - that is, child components calling mutations that modify parent component query cache will not trigger re-render of the parent component. Really weird behaviour. Can’t really even think of a workaround without making a network request by forcing a refetch. Using v3.4.16

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mutations in Apollo Client - Apollo GraphQL Docs
If a refetched query's response differs from your update function's modifications, your cache and UI are both automatically updated again. Otherwise, your users ......
Read more >
Apollo Client: Component doesn't render after cache update ...
Create item query, it creates an item and returns it as an array: import gql from "graphql-tag"; const CREATE_ITEM = gql` mutation createItem($ ......
Read more >
Trouble re-rendering another component after useMutation ...
I have two components: one is the main user dashboard and the ... But this doesn't cause the user dashboard component to re-render...
Read more >
GraphQL Mutations and Caching using Apollo Client
Notice, this is similar to how we defined queries in the previous blog post. Once the mutation is defined, the useMutation hook is...
Read more >
Managing State with React and Apollo Client | DoltHub Blog
Handling queries. Now that our cache is configured, we can use Apollo's useQuery hook to fetch data within our components, as well as...
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