useMutation updates cache but does not re-render components querying same object
See original GitHub issueIntended 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:
The mutation running and returning the new objects w/ non-null latestValidPropertyInspection
:
apollo chrome extension showing the cache updated after the mutation ran:
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:
- Created 4 years ago
- Reactions:35
- Comments:42 (5 by maintainers)
Top 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 >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
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:
Now I have a component that do
useQuery
to fetch “me”, and the matchmakings, in a single query.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 docache.modify
to change one of the matchmaking.joined date, the component rerenders (no bug).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 rerenderedIt 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.
I’ve also noticed what @dan-cooke said.
useQuery
hook returns stale data, even though cache is updated correctly. Actually the component callinguseQuery
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 arefetch
. Using v3.4.16