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

nonreactive directive on a defer fragment #11616

Open thomaswelton opened 8 months ago

thomaswelton commented 8 months ago

Issue Description

The nonreactive directive is not compatible with deferred fragments for the initial fetch of a query.

Given this query

fragment NameFragment on Playlist {
    name
  }

query GetPlaylists {
    featuredPlaylists {
      edges {
        node {
          id
          ... @defer {
            ...NameFragment @nonreactive
          }
        }
      }
    }
  }

I would expect that the query results would contain my array of nodes with the id parameter loaded. Then when the defer data is loaded incrementally I'd expect that the nodes array would be referentially stable due to the fact that the NameFragement is @nonreactive, but this is not the case.

In our real world case we are fetching an array of results to show on a list view and map. Some of the data in these results is slow to load so we have used defer. However the result is not referentially stable which is causing some performance issues where our whole list is rerendered multiple times.

See also a thread on discord

Link to Reproduction

https://github.com/thomaswelton/react-apollo-error-template/tree/defer-nonreactive

Reproduction Steps

Run the development server locally. See that the heading on the page contains a count of the amount of times that the query results array has changed. See that once the deffered data loads the render count is 2 instead of the expected 1.

@apollo/client version

3.9.4

jerelmiller commented 8 months ago

Thanks for the report and reproduction! We'll get to this when we can 🙂