DEV Community

Cover image for Como evitar refetch para atualizar os dados do cache do Apollo Client (React)?
Eric Endo
Eric Endo

Posted on • Updated on <time datetime="2021-02-27T14:41:02Z" class="date-no-year">Feb 27</time>

Como evitar refetch para atualizar os dados do cache do Apollo Client (React)?

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 (com 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:

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
}
Enter fullscreen mode Exit fullscreen mode

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:

const UPDATE_POST = gql`
  mutation UpdatePost(
    $id: ID!,
    $title: "String,"
    $description: "String"
  ) {
    updatePost(
      id: $id,
      title: "$title,"
      description: "$description"
    ) {
      id
+     title
+     description
    }
  }
`
Enter fullscreen mode Exit fullscreen mode

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 (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 (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 (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

Discussion (0)