Query refetch on local state change

Hello,

I’m using Apollo Client to paginate a feed of data.
My local state contains two tabs that are supposed to fetch either active data or draft data.

I’ve created a query that takes the active status to fetch the data from.
When the query first loads (when the component mounts), it works very well and I manage to paginate the data with fetchMore.
However, when I click on the second tab, the query is not rerun and the cache is not invalidated.

I’ve managed to make it work somehow by using refetch when the local state change, but I’d like to know if there is a better/cleaner way.

I’d have expected the query to rerun on its own as the state variable had changed but it does not fire a new request and it fetches the data from the cache even though the variable has change.

Here is the code:

// This works perfectly fine.
const { loading, error, data, fetchMore, refetch } =
    useQuery(FEATURED_VIDEOS, {
      variables: {
        filters: {
          limit: 12,
          active: activeTab === "featured"
          offset: 0,
        },
      },
    });

// This is called to change the active tab by updating React state
 const changeTab = (newTab: string) => {
    setSelected(null);
    setActiveTab(newTab);
    refetch({
      filters: {
        limit: 12,
        offset: data?.featuredVideos.length,
        active: newTab === "featured",
      },
    });
  };

Thanks for your help,

Update:

I’ve also managed to make this work by using client.resetStore() instead of the manual refetch.
Can you tell me which way is better ?

Thanks in advance,

I reckon it might have something to do with how you set the type policies for your paginated field. See the documentation here: Core pagination API - Client (React) - Apollo GraphQL Docs
… and here: Customizing the behavior of cached fields - Client (React) - Apollo GraphQL Docs

Did you set keyArgs: false? If so, the cache key for your query will be built without any of the arguments, causing every combination of arguments to reference the same cache object. This would mean that changing the active tab would not cause a refetch.

I would recommend separating the active argument from the pagination arguments, like so:

filters: {
    active: activeTab === 'featured',
},
pagination: {
    limit: 12,
    offset: 0,
},

Then you can set keyArgs: ['filters'] in the type policies to tell Apollo that the filters argument is relevant for building cache objects and the pagination argument is not.

Wow, thanks a lot for your help.

I had set keyArgs but with a field from the query result, not the query params.
To make it work, I now use:
keyArgs: ['filters', ['active']] and the query is now gracefully resent when the active parameters change.

Thanks again for your insight,

No problem, glad it worked out!