Noções básicas de dados de cache no cliente Apollo React GraphQL

Saidur Rahman Blocked Unblock Seguir Seguindo 1 de janeiro

Este é um playbook com alguns dos padrões comuns para acessar e manipular o armazenamento / cache no React Apollo GraphQL. Como uma cartilha, leia https://www.apollographql.com/docs/react/essentials/get-started.html#installation

Acesso direto ao cache

Para acessar o cache de dados, você pode usar os métodos readQuery , readFragment , writeQuery e writeFragment da classe Apollo Client por meio da interface DataProxy .

readQuery

readQuery nunca fará uma solicitação ao seu servidor GraphQL. Ele sempre lerá do cache, senão throw um erro; Portanto, lembre-se de ler apenas os dados que você sabe que tem na loja.

Exemplo de uso de readQuery

Como alternativa, o método de query pode enviar uma solicitação ao seu servidor se os dados apropriados não estiverem em seu cache.

readFragment

readFragment permite ler dados de qualquer nó que você tenha consultado, enquanto readQuery só permite ler dados do tipo de consulta raiz.

Para que isso funcione, você precisa do id dos dados retornados pela função dataIdFromObject , conforme definido ao inicializar o ApolloClient. Se o id não existir no cache, o readFragment retornará null. Se o id existir, mas não tiver um campo especificado pela consulta de fragmento, será gerado um erro.

O aspecto mágico é que o objeto pode ser de qualquer lugar – pode estar na loja como um singleton ou de uma lista ou mesmo de uma mutação. Enquanto o servidor GraphQL lhe fornecer o objeto com a forma de fragmentos, você poderá lê-lo no cache.

writeQuery e writeFragment

Você também pode gravar dados no cache. Observe que isso só alterará os dados em seu cache local e não alterará os dados em seu servidor. Se você recarregar, as alterações desaparecerão.

Estes métodos têm a mesma assinatura como função readQuery e readFragment homólogos, excepto requerem um adicional de data variável a ser transmitida.

Qualquer assinante do armazenamento do Apollo Client verá essas atualizações e processará a interface do usuário de acordo.

Exemplo de uso de writeQuery

Por que usar o repositório de dados?

Ignorando o cache

Quando faz sentido não usar o cache para uma operação específica, você pode usar o fetchPolicy network-only ou no-cache na sua consulta.

  • network-only salva a resposta ao cache para uso posterior, ignorando a leitura e forçando uma solicitação de rede. Isso é para assegurar a consistência dos dados com o servidor, mas isso custa ao usuário uma resposta instantânea.
  • no-cache política no-cache não lê, nem grava no cache com a resposta. Ele sempre fará uma solicitação usando sua interface de rede para o servidor. Ao contrário da política somente de rede, ela não gravará nenhum dado no cache após a conclusão da consulta.

Exemplo de uso de fetchPolicy somente para rede e em cache primeiro para consulta

Há mais a fetchPolicy do que essas duas variantes. Leia mais sobre fetchPolicy em https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-config-options-fetchPolicy

Atualizando depois de uma mutação

Se você quiser adicionar algo a uma lista de objetos sem refazer toda a lista ou se houver alguns objetos aos quais você não pode atribuir um identificador de objeto, o Apollo Client não poderá atualizar as consultas existentes.

  • refetchQueries é a maneira mais simples de atualizar o cache. Com refetchQueries é possível especificar uma ou mais consultas que você deseja executar depois que uma mutação for concluída para refazer as partes do armazenamento que podem ter sido afetadas pela mutação.

Exemplo de uso de refetchQueries após mutação

Se você chamar refetchQueries com uma matriz de strings, o Apollo Client procurará consultas previamente chamadas que tenham os mesmos nomes que as strings fornecidas e, em seguida, refazer essas consultas com suas variáveis atuais. Você também pode importar consultas para outros componentes para garantir que esses componentes sejam atualizados.

  • update permite que você faça alterações em seu modelo de dados em resposta a uma mutação da maneira que desejar.

Exemplo de uso de atualização após mutação

Note que há todo um conjunto de desafios técnicos com atualizações após a mutação. Leia mais sobre a interface do usuário otimista em https://www.apollographql.com/docs/react/features/optimistic-ui.html

Carregamento Incremental

Se você deseja manipular a paginação de rolagem infinita ou ao carregar mais dados em vez de jogar fora uma lista, basta anexar os dados recém-carregados à lista que já está na loja, você pode usar o fetchMore .

Exemplo de uso de fetchMore para carregamento incremental

O método fetchMore usa um mapa de variáveis a serem enviadas com a nova consulta. Precisamos passar um deslocamento para evitar a busca de itens que já estão na loja. Observe que o mapa de variáveis é mesclado com o que foi especificado para a consulta associada ao componente, por exemplo, não é necessário passar limites depois de definido.

Por padrão, a consulta fetchMore é a consulta associada ao contêiner, mas também pode receber uma consulta chamada argument, que pode ser um documento GraphQL contendo uma consulta.

A diretiva @connection

Consultas paginadas são a mesma consulta, com exceção de que as chamadas para fetchMore atualizam a mesma chave de cache. Como os campos que lidam com paginação geralmente têm alguns argumentos extras, como cursor ou limite, queremos ter certeza de que temos uma chave de cache limpa que não inclua esses argumentos.

A diretiva @connection introduzida no Apollo Client 1.6 ajuda a especificar que os dados retornados desse campo devem ser armazenados sob a chave fornecida, facilitando a anexação a uma lista devido a resultados de mutação ou paginação.

Exemplo de uso da diretiva @connection

Se não usarmos a diretiva @connection nesse campo, nossas funções de atualização de mutação precisarão reproduzir o conjunto exato de argumentos originalmente transmitidos para esse campo.

Como a diretiva de conexão especifica uma chave de armazenamento personalizada para resultados, também não precisamos fornecer nossos argumentos de paginação, como limites, deslocamentos ou cursores, para acessar nossos dados armazenados em cache. Mesmo com várias fetchMore , os resultados de cada atualização de feed sempre farão com que a chave de feed na loja seja atualizada com os valores acumulados mais recentes.

Também podemos usar o argumento de filter opcional da diretiva @connection para incluir o argumento de consulta de type na chave de armazenamento, o que resulta em vários valores de armazenamento que acumulam consultas de cada tipo de feed.

Benefício de usar a diretiva @connection em nossas mutações

Leia mais sobre a diretiva @connection em https://www.apollographql.com/docs/react/features/pagination.html#connection-directive e https://www.apollographql.com/docs/react/advanced/caching. html # connection-directive

Redirecionamentos de cache com cacheRedirects

Em alguns casos, uma consulta solicita dados que já existem no armazenamento do cliente com uma chave diferente. Um exemplo muito comum disso é quando sua interface do usuário tem uma visualização de lista e uma visualização de detalhes que usam os mesmos dados.

Consulta para listar BooksQuery para mostrar detalhes de um livro

Nota: Os dados retornados pela consulta de lista devem incluir todos os dados que a consulta específica precisa. Se a consulta de livro específica buscar um campo no qual a consulta de lista não retorna, o Apollo Client não poderá retornar os dados do cache.

Sabemos que os dados provavelmente já estão no cache do cliente, mas como ele é solicitado com uma consulta diferente, o Apollo Client não sabe disso. Para informar ao Apollo Client onde procurar os dados, podemos definir resolvedores personalizados.

Solucionador personalizado para usar o cacheRedirects

Nota: Isso também funcionará com métodos personalizados de dataIdFromObject, desde que você use o mesmo.

Nota: getCacheKey é passado dentro do terceiro argumento para o resolvedor para gerar a chave do objeto com base em seu __typename e id .

Para descobrir o que você deve colocar na propriedade __typename , execute uma das consultas no GraphiQL e obtenha o campo __typename .

Repor a loja

client.resetStore redefine completamente o cache da Apollo. Ele também refetiga qualquer uma das suas consultas ativas e é assíncrono.

Se você deseja limpar o repositório, mas não deseja refazer as consultas ativas, use client.clearStore() vez de client.resetStore() .

Exemplo de uso de client.resetStore

Para registrar uma função de retorno de chamada a ser executada após o armazenamento ser reconfigurado, use client.onResetStore e passe seu retorno de chamada. Para registrar vários retornos de chamada, chame client.onResetStore novamente. Todos os retornos de chamada são colocados em uma matriz e executados simultaneamente.

Exemplo de uso de client.onResetStore

Nota: Se você estiver usando o estado apollo-link-state para o gerenciamento de estado local e chamando client.resetStore em qualquer lugar em seu aplicativo, use client.onResetStore para gravar os valores padrão no cache.

Você também pode chamar client.onResetStore de seus componentes React. Isso pode ser útil se você quiser forçar sua UI a ser renderizada novamente depois que a loja for redefinida.

Se você desejar cancelar a assinatura de suas chamadas de retorno de client.resetStore , use o valor de retorno de client.onResetStore para sua função de cancelamento de assinatura.

Cancelar a inscrição de seus retornos de chamada do client.onResetStore

Texto original em inglês.