Como evitar refetch para atualizar os dados do cache do Apollo Client (React)?
Tags: graphql, apollo, react, braziliandevs
Published: 2021-02-23 19:51:55

### TLDR
> Inclua os valores atualizados no retorno da `mutation`. O Apollo vai fazer sua mágica 🪄 e atualizar os dados do cache, sem precisarmos utilizar o `refetch()`.

---

Se você usa [Apollo Client](https://www.apollographql.com/docs/react/) (com [hooks](https://www.apollographql.com/docs/react/api/react/hooks/), por favor!) na sua aplicação React, chances de você já ter feito algo desse tipo para atualizar os dados após uma `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() // <- precisamos mesmo disso?
  }

  // ...render e demais partes do component
}
```

O ponto é: esse `refetch()` após o `updatePost()` pode ser evitado (consequentemente evitando uma requisição desnecessária), simplesmente adicionando alguns campos no retorno da `mutation`:

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

Por que isso funciona? Pra entender melhor, precisamos entender dois conceitos do Apollo: como ele cacheia os dados, e como ele atualiza os dados cacheados.

Para a parte do [cacheamento](https://www.apollographql.com/docs/react/caching/cache-configuration/) (tradução livre):

> o Apollo Client armazena os resultados de suas queries GraphQL em um cache normalizado, na memória. Isso possibilita que seu cliente responda a queries futuras envolvendo os mesmos dados sem enviar requisições de rede desnecessariamente.

Para a parte da [atualização](https://www.apollographql.com/blog/demystifying-cache-normalization/) (tradução livre):

> Para o Apollo Client conseguir atualizar o cache automaticamente, temos que lembrar de **sempre retornar os novos dados nas respostas das operações**.

> Para respostas de `queries`, esse é o ponto. Todo o propósito de uma query é retornar dados e cacheá-los.

> Mas para `mutations`, como o `editTodo` que alterar uma única entidade, nós devemos ser capazes de atualizar o item automaticamente se retornarmos o valor na resposta da mutation.

Então para `mutations` como essa do exemplo, de uma única entidade e que possua id, basta **incluírmos os valores atualizados no retorno da mutation que o Apollo faz sua mágica 🪄 e atualiza os dados do cache, sem precisarmos utilizar o `refetch()`.**

---

Mas... e quando estamos falando de outros casos, quando as entidades não possuem um campo `id`, ou de `mutations` que impactam dados derivados da entidade atualizada, por exemplo?

[Este post do Apollo Blog](https://www.apollographql.com/blog/demystifying-cache-normalization/) (que eu já linkei na parte da atualização) fala de algumas estratégias - mas isso pode ser algo para discutirmos mais em um (ou alguns) post(s) futuro(s).

---

Imagem de fundo da capa por [SpaceX](https://unsplash.com/@spacex?utm_source=devto&utm_medium=referral)