urql-graphql / urql

The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
https://urql.dev/goto/docs
MIT License
8.57k stars 444 forks source link

Query operation is fetched twice (not deduped) when other SSR data is available #3384

Closed jet2jet closed 10 months ago

jet2jet commented 10 months ago

Describe the bug

When query for different fields in same type (such as requesting Todo.description and requesting Todo.tags), one query is fetched twice. This only happens when SSR data is available.

I suspect following lines (https://github.com/urql-graphql/urql/blob/%40urql/exchange-graphcache%406.3.3/exchanges/graphcache/src/cacheExchange.ts#L134-L140)

        // Upon completion, all dependent operations become reexecuting operations, preventing
        // them from reexecuting prior operations again, causing infinite loops
        const _reexecutingOperations = reexecutingOperations;
        if (operation.kind === 'query') {
          (reexecutingOperations = dependentOperations).add(operation.key);
        }
        (dependentOperations = _reexecutingOperations).clear();

When operation.kind is not 'query', reexecutingOperations will not be changed, causing reexecutingOperations and dependentOperations is equal. I think this affects the line https://github.com/urql-graphql/urql/blob/%40urql/exchange-graphcache%406.3.3/exchanges/graphcache/src/cacheExchange.ts#L378 and results fetching is performed again.
(When moving reexecutingOperations = dependentOperations code to outer of if, the problem seems to be fixed.)

Reproduction

https://github.com/jet2jet/urql-multi-query-with-ssr-test

  1. Clone the repository and initialize (npm ci)
  2. Run npm run start
  3. Open http://localhost:3000 and developer tool for the site
  4. Enter 1 to ID: and click Get
  5. TodoTags query is fetched twice (Expected: both TodoDetail and TodoTags queries are fetched once)

Urql version

urql v4.0.5 @urql/exchange-graphcache v6.3.3

Validations