Prevent apollo client from automatically refetching queries after updating cache

Viewed 464

I have a React application with the apollo client using hooks. I have a dashboard page which has the following query

dashboard(uniquePageId: $id) {
      id
      tasks(filterData: $taskFilter) {
        taskId
        taskName
        taskTagLine
        taskStatus
        taskImagePath
      }
    }
  }

The data is fetched using the useLazyQuery hook with the following configuration:

  const [
    taskFilterQuery,
    { error: taskFetchError, loading: taskFetchLoading },
  ] = useLazyQuery<TaskSummaryResponse, DashboardQueryVariables>(
    UPDATE_TASKS_DATA,
    {
      errorPolicy: "all",
      fetchPolicy: "cache-and-network",
    }
  );

Whenever filters are applied, I'm calling the function like this

const handleTaskFilterChange = useCallback(
    function (filterData: TasksSummaryFilter) {
      taskFilterQuery({
        variables: {
          taskFilter: filterData,
          id: PAGE_ID,
        },
      });
    },
    [taskFilterQuery]
  );

I have another view that lets the user update a task's status. Once the update is complete, I want to update the list and remove the task whose status was updated from the currently viewed list. So I provide an update function to the useMutation hook and update the cache. But as soon as the cache is updated, the apollo client is re-fetching the dashboard query. This is my update cache code

try {
    const tasksSummary = cache.readFragment<TaskSummaryFragment>({
      fragment: TASKS_DATA,
      id: cache.identify({ __typename: DASHBOARD_DATA, id: queryVariables.id }),
      variables: {
        taskFilter: queryVariables.taskFilter,
      },
    });

    if (!tasksSummary) {
      return;
    }

    const updatedTasks = tasksSummary.tasks.filter(
      ({ taskId }) => taskIdToCheck !== taskId
    );

    cache.writeFragment<TaskSummaryFragment>({
      fragment: TASKS_DATA,
      id: cache.identify({ __typename: DASHBOARD_DATA, id: queryVariables.id }),
      variables: {
        taskFilter: queryVariables.taskFilter,
      },
      data: {
        tasks: updatedTasks,
      },
      broadcast: false,
    });
  } catch (cacheUpdateError) {
    console.error("Updating task cache failed", cacheUpdateError);
  }

Once the cache update is complete the task query is automatically re-fetched. This causes an unnecessary network round trip. If I comment out this code then post-mutation the query is not re-fetched. Is there any way to prevent apollo from doing this?

Project versions

  "react": "^16.13.1",
  "react-dom": "^16.13.1",
  "@apollo/client": "^3.1.3",
1 Answers

For anyone wondering how to fix this behavior, you need to upgrade the apollo repo. I upgraded to the latest at the time of writing this answer: "@apollo/client": "^3.5.9"

Code changes:

      fragment: TASKS_DATA,
      id: cache.identify({ __typename: DASHBOARD_DATA, id: queryVariables.id }),
      variables: {
        taskFilter: queryVariables.taskFilter,
      },
      data: {
        tasks: updatedTasks,
      },
      // broadcast: false, (remove this, default behavior is true)
    });

Go to your active query and update the nextFetchPolicy

fetchPolicy: "cache-and-network",
nextFetchPolicy: "cache-first",

The above ensures that on cache update the query fetches data from the cache only

Related