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

Deduplication issue with react #12216

Closed
canda opened this issue Dec 12, 2024 · 4 comments
Closed

Deduplication issue with react #12216

canda opened this issue Dec 12, 2024 · 4 comments

Comments

@canda
Copy link

canda commented Dec 12, 2024

Issue Description

Hey there!

I'd like to ask for a little help here 🙏.
I am seeing duplicate network requests on my React application.
I was able to reproduce this issue on a simple example with two useQuery hooks with almost identical queries. One asks for the details in the roadster object, the other one asks for the name in the roadster object.

The result:
4 network requests are triggered:

  1. ExampleQuery2 (fine)
  2. IntrospectionQuery (fine I guess)
  3. ExampleQuery1 (fine)
  4. ExampleQuery2 (duplicated ❌)
ExampleQuery2 IntrospectionQuery ExampleQuery1 ExampleQuery2
image image image image

Link to Reproduction

https://codesandbox.io/p/sandbox/apollo-react-deduplication-bug-cmcv2h?file=%2Fsrc%2FApp.tsx%3A44%2C53-45%2C32

Reproduction Steps

Go to https://cmcv2h.csb.app/ and open devtools.
Refresh the page, and you should see the repeated queries.

@apollo/client version

3.12.2

Copy link

triagster bot commented Dec 12, 2024

Related issues:

Was this useful? Use the thumbs up or thumbs down reaction to give feedback.

@jerelmiller
Copy link
Member

jerelmiller commented Dec 12, 2024

Hey @canda 👋

If you check your console, you'll see a warning about this which takes you to this error link which reads:

Cache data may be lost when replacing the roadster field of a Query object.

This could cause additional (usually avoidable) network requests to fetch data that were otherwise cached.

To address this problem (which is not a bug in Apollo Client), either ensure all objects of type Roadster have an ID or a custom merge function, or define a custom merge function for the Query.roadster field, so InMemoryCache can safely merge these objects:

existing: { "__typename": "Roadster", "details": "Elon Musk's Tesla Roadster is an electric sports car that served as the dummy payload for the February 2018 Falcon Heavy test flight and is now an artificial satellite of the Sun. Starman, a mannequin dressed in a spacesuit, occupies the driver's seat. The car and rocket are products of Tesla and SpaceX. This 2008-model Roadster was previously used by Musk for commuting, and is the only consumer car sent into space." } 
incoming: { "__typename": "Roadster", "name": "Elon Musk's Tesla Roadster" }

For more information about these options, please refer to the documentation:

Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers
Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects

This issue here is that the cache doesn't know how to merge these objects together since they are non-normalized. The default behavior is to completely replace non-normalized objects. Because of this, whatever request completes second will overwrite the results from the first request. That causes data to disappear, so the first query thinks it needs to refetch again to fulfill the result of the query.

You can fix this either by querying for id, or by writing your own merge function. In general keep an eye out for those warnings as this can help diagnose the issue.

@canda
Copy link
Author

canda commented Dec 14, 2024

Oh, I missed the console message 🙈
Thank you for the quick response and the clear explanation. Very helpful.
For future reference, in case somebody runs into the same issue, I was able to fix this example by using the default merge strategy from typePolicies.

new InMemoryCache({
  typePolicies: {
    Roadster: {
      merge: true,
    },
  },
})

This made the Roadster cache contain both name and details on the example.

image

https://codesandbox.io/p/sandbox/apollo-react-deduplication-bug-forked-s4y84k?file=%2Fsrc%2FApp.tsx%3A45%2C12-51%2C7&workspaceId=ws_4zqL7rCcJVbZ1YU2aigNLb

@canda canda closed this as completed Dec 14, 2024
Copy link
Contributor

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants