Avoiding refetch to update Apollo Client cached data (React)
Tags: graphql, apollo, react
Published: 2021-02-27 14:19:20

### TLDR
> Include updated fields in `mutation` response: Apollo will do their magic 🪄 and update the cached data. No need to `refetch()`.

---

If you use [Apollo Client](https://www.apollographql.com/docs/react/) (with [hooks](https://www.apollographql.com/docs/react/api/react/hooks/) please!) in your React project, chances are that you have already done something like this to update the data after a mutation:

```jsx
const GET_POST = gql`
  query GetPost($id: ID!) {
    post(id: $id) {
      id
      title
      description
    }
  }
`

const UPDATE_POST = gql`
  mutation UpdatePost(
    $id: ID!,
    $title: String,
    $description: String
  ) {
    updatePost(
      id: $id,
      title: $title,
      description: $description
    ) {
      id
    }
  }
`

function PostDetails({ id }) {
  const { data, refetch } = useQuery(
    LIST_POSTS,
    { variables: { id } }
  )
  const [updatePost] = useMutation(UPDATE_POST)

  async function editPost(formValues) {
    await updatePost({ variables: formValues })
    refetch() // <-- do we really need it?
  }

  // ...render and other component parts
}
```

Can we avoid the `refetch()` after `updatePost()` (thus avoiding one unnecessary request)? Yes, by simply adding some fields to the mutation return:

```diff
const UPDATE_POST = gql`
  mutation UpdatePost(
    $id: ID!,
    $title: String,
    $description: String
  ) {
    updatePost(
      id: $id,
      title: $title,
      description: $description
    ) {
      id
+     title
+     description
    }
  }
`
```

Why does this work? To answer this, we need to understand two Apollo concepts first: data caching and cache updating.

For the [caching](https://www.apollographql.com/docs/react/caching/cache-configuration/) part:

> Apollo Client stores the results of its GraphQL queries in a normalized, in-memory cache. This enables your client to respond to future queries for the same data without sending unnecessary network requests.

For the [updating](https://www.apollographql.com/blog/demystifying-cache-normalization/) part:

> In order for Apollo Client to update the cache automatically, we have to remember to **always return the new data in operation responses**.

> For `query` responses, that’s the point. The entire purpose of a query is to return data and cache it.

> But for `mutations`, like `editTodo` that change a single entity, we should be able to update the item automatically if we return the value in the mutation response.

So, for `mutations` like this one from the example (a single entity with id), just **include updated fields in the mutation response: Apollo will do their magic 🪄 and update the cached data. No need to `refetch()`.**

---

But... what about other cases, when entities have no `id` field or `mutations` that change data related to the updated entity, for example?

This [Apollo Blog post](https://www.apollographql.com/blog/demystifying-cache-normalization/) (already linked in the updating part) talks about some strategies for those cases - but we can talk more about those cases in one (or more) post(s) in the future.

---

PS 1: English is not my native language. Feel free to suggest any corrections, point grammatical errors, and etc.

PS 2: check the [original post here](https://dev.to/endoooo/como-evitar-refetch-para-atualizar-os-dados-do-apollo-client-react-5d9l) (in Brazilian Portuguese)

---

Cover background image by [SpaceX](https://unsplash.com/@spacex?utm_source=devto&utm_medium=referral)