apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.38k stars 2.66k forks source link

Multiple queries relying on local state do not update final instance #5407

Closed Gazler closed 4 years ago

Gazler commented 5 years ago

I discovered this bug in an application I am building, where two different sections of the application are dependant on the value stored in local state.

I was able to replicate the issue in the react-apollo-error-template repository.

https://github.com/Gazler/react-apollo-error-template/tree/local-state-error

https://codesandbox.io/s/github/Gazler/react-apollo-error-template/tree/local-state-error

It is perhaps easiest to describe the issue with some screenshots. I had initially built this with two different queries (because that is how I discovered the issue), please refer to the repository above for the full code listings.

Initially, the bestFriend is set to "1" which is used by both the <FriendList> and <AddressBook>:

  <div style={{display: "flex"}}>
    <FriendList />
    <AddressBook />
  </div>

2-different

And the following mutation:

  client.mutate({mutation: CHANGE_BEST_FRIEND, variables: { id: "2" }})

After triggering the mutation:

2-different-triggered

The expectation would be for "Sara Smith" to be highlighted in both lists.

The mutation actually triggers a subsequent mutation. This is required to trigger the bug.

changeBestFriend: (_, { id }) => {
  updateFriendId(null);
  client.mutate({mutation: TRIGGER_NEW_BEST_FRIEND, variables: { id: id }});
},
triggerNewBestFriend: (_, { id }) => updateFriendId(id)

Upon further inspection, I noticed that they don't need to be separate queries, multiple instances of the same query will also trigger this.

  <div style={{display: "flex"}}>
    <FriendList />
    <FriendList />
  </div>

This gets more interesting when adding more than 2 instances:

  <div style={{display: "flex"}}>
    <FriendList />
    <FriendList />
    <FriendList />
    <FriendList />
    <FriendList />
  </div>

5-same-triggered

This would suggest to me that potentially there is an off-by 1 error? I'm not super familiar with the code base, but will have a look around to see if I can fix this. Any pointers would be appreciated.

Please let me know if you require any more details.

Versions

System: OS: Linux 4.15 Ubuntu 18.04.2 LTS (Bionic Beaver) Binaries: Node: 10.16.3 - ~/.asdf/installs/nodejs/10.16.3/bin/node Yarn: 1.3.2 - ~/.yarn/bin/yarn npm: 6.9.0 - ~/.asdf/installs/nodejs/10.16.3/bin/npm Browsers: Chrome: 75.0.3770.142 Firefox: 69.0.1 npmPackages: @apollo/react-hooks: ^3.0.0 => 3.0.0 apollo-cache-inmemory: ^1.6.3 => 1.6.3 apollo-client: ^2.6.4 => 2.6.4 apollo-link: ^1.2.12 => 1.2.12

Gazler commented 4 years ago

This appears to have been fixed between react-hooks v3.1.4 and v3.1.5 - probably in this commit https://github.com/apollographql/apollo-client/commit/ea442030dc33da4334974cebafd9ad0e2f71aa6a#diff-6811d3fb33f26bd505d724338f96e277