Apollo-client: Subscription updateQuery triggers refetch

Created on 24 May 2020  路  4Comments  路  Source: apollographql/apollo-client

Intended outcome:
When receiving data from a websocket subscription, _only_ the original useQuery data object should get modified.

Actual outcome:
When receiving data from a websocket subscription, the original query as defined in useQuery is run again as if refetch was called.

This happens each time new subscription data is received.

How to reproduce the issue:

The issue occurs with this simple setup:

const MyComponent = () => {
  const { subscribeToMore } = useQuery(MY_QUERY, {
    fetchPolicy: 'cache-and-network',
  })

  useEffect(() => {
    return subscribeToMore({
      document: MY_SUBSCRIPTION,
      updateQuery: (prev, { subscriptionData }) => {
        return subscriptionData.data
      },
    })
  }, [])

  return null
}

MY_QUERY and MY_SUBSCRIPTION are identical (except for the query and subscription prefix) and include an id for all types.

Versions

  System:
    OS: Linux 4.15 Ubuntu 18.04.4 LTS (Bionic Beaver)
  Binaries:
    Node: 12.16.2 - ~/.nvm/versions/node/v12.16.2/bin/node
    npm: 6.14.4 - ~/.nvm/versions/node/v12.16.2/bin/npm
  Browsers:
    Chrome: 83.0.4103.61
    Firefox: 76.0.1
  npmPackages:
    @apollo/client: ^3.0.0-beta.50 => 3.0.0-beta.50 
    @apollo/link-ws: ^2.0.0-beta.3 => 2.0.0-beta.3

This behavior seems to have been introduced in 3.0.0-beta.46.

鈿涳笍 React-related

Most helpful comment

I'm pretty sure the same thing is causing fetchMore not to work either. If you have a fetchPolicy that does network fetches, the data is refetched, overwriting your updated data.

E.g. something like this:

const MyComponent = () => {
  const { fetchMore } = useQuery(MY_QUERY, {
    fetchPolicy: 'cache-and-network',
  })

  useEffect(() => {
    fetchMore({variables: {cursor: 1}})
  }, [])

  return null
}

All 4 comments

I'm pretty sure the same thing is causing fetchMore not to work either. If you have a fetchPolicy that does network fetches, the data is refetched, overwriting your updated data.

E.g. something like this:

const MyComponent = () => {
  const { fetchMore } = useQuery(MY_QUERY, {
    fetchPolicy: 'cache-and-network',
  })

  useEffect(() => {
    fetchMore({variables: {cursor: 1}})
  }, [])

  return null
}

Could someone provide a small runnable reproduction that demonstrates this? Thanks!

I suspect this issue has the same cause as #6327 and #6305, which have runnable examples.

This is fixed in @apollo/[email protected].

Was this page helpful?
0 / 5 - 0 ratings