У вас включен AdBlock или иной блокировщик рекламы.

Пожалуйста, отключите его, доход от рекламы помогает развитию сайта и появлению новых статей.

Спасибо за понимание.

В другой раз
DevGang блог о програмировании
Авторизоваться

Управление локальным состоянием с помощью Apollo Client и React Hooks 

В этом посте мы узнаем, как работать с вашими локальными данными в Apollo Client.

Потребность в локальном состоянии

Современные веб и мобильные приложения стали чрезвычайно управляемыми данными. Создание больших одностраничных приложений является сложным процессом из-за постоянно меняющихся данных с течением времени. Обнаружение этих изменений данных и повторное отображение интерфейса каждый раз является болезненным.

Мы хотим получить доступ ко всем свойствам, хранящимся в различных компонентах нашего приложения, наиболее оптимальным способом.

Введенние в Apollo Client

Apollo Client имеет встроенные возможности обработки локальных состояний, которые позволяют вам хранить ваши локальные данные в кэше Apollo вместе с вашими удаленными данными. Чтобы получить доступ к вашим локальным данным, просто запросите их с помощью GraphQL. Вы даже можете запросить локальные и серверные данные в одном запросе! - Apollo Docs

Давайте углубимся в настройку клиента apollo и локального состояния:

Настройка клиента Apollo 🚀

const client = new ApolloClient({
 link, // httpLink
 cache, 
 resolvers
 typeDefs,
});

Теперь Apollo Client состоит из нескольких ключевых частей.

  • Apollo link - используется для настройки клиента Apollo network layer. Это означает, что ссылка apollo позволяет настроить способ отправки запросов по HTTP.
  • Cache - клиент Apollo использует экземпляр Apollo Cache для управления своей стратегией кэширования
  • Resolvers - для реализации вашего локального обновления состояния в виде мутации GraphQL
  • TypeDefs - Чтобы дополнительно установить на стороне клиента схему которая будет использоваться с Apollo Client. Эта схема используется для самоанализа в Apollo Client Devtools, где вы можете изучить свою схему в GraphiQL.

Позволяет подключить каждую из вышеуказанных частей. Мы установим локальное состояние для свойства под названием isDarkModeEnabled.

import { InMemoryCache, NormalizedCacheObject } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';

// typedefs and resolvers
import StateResolvers from './resolvers';
import typeDefs from './typeDefs';

export function createClient(): ApolloClient {
   const cache = new InMemoryCache();
   
   // create http link
   const httpLink = new HttpLink({
       uri: 'https://example.com/graphql'
   });

   // Helper function to get data from the cache
   const getState = (query: any): IState => {
       return cache.readQuery({ query }).state;
   };

   // Helper function to write data back to the cache
   const writeState = (state: IState) => {
       return cache.writeData({ data: { state } });
   };

   // initial apollo local state
   const initState = () => {
       const state = {
           appState: defaultAppState,
           __typename: 'State',
       };

       writeState(state);
   };

   const client = new ApolloClient({
       link,
       cache,
       resolvers: StateResolvers(getState, writeState),
       typeDefs,
   });
}

Сначала мы создаем новый экземпляр Apollo InMemoryCache. Здесь будет жить наше локальное состояние. Затем мы определяем наш сетевой уровень, чтобы клиент apollo подключался к серверу GraphQL.

getState и writeState две вспомогательные функции, которые читают и записывают данные в кеш. Вспомогательные функции реализуют cache.readData и cache.writeData и действуют как методы получения и установки в кэше. Далее мы инициализируем наше состояние apollo значениями по умолчанию. Важно записать начальное состояние в кэш, чтобы любые компоненты, запрашивающие данные до запуска мутации (обновления локального состояния), не выдавали ошибку. Наконец, мы инициализируем наш клиент Apollo.

Давайте приступим к определению typeDefs и Resolvers. У нас есть простая схема, которая определяет состояние нашего приложения.

import gql from 'graphql-tag';

const typeDefs = gql `
   type appState {
       isDarkModeEnabled: Boolean
   }
`;

export default typeDefs;

Управление кешем 📝

Кеш Apollo - это единственный источник правды или «хранилище» в терминах редукции, когда вы используете Apollo Client для управления состоянием вашего приложения.

import gql from 'graphql-tag';

const getAppState = gql`
   query {
       state @client {
           appState {
             isDarkModeEnabled
           }
       }
   }
`;

export default (getState, writeState) => {
   return {
       Mutation: {
            updateAppState(_, appState) {
               // получить текущее / начальное состояние из кеша
               const state = getState(getAppState);
   
               const newState = {
                   ...state,
                   appState: Object.assign({}, state.appState, appState),
               };
               
               writeState(newState);
               return newState;
           },
       }
   }
}

С помощью функций readState и writeState мы запрашиваем начальное / текущее состояние, а затем обновляем его новыми значениями. Для запроса локального состояния мы использовали директиву @client, указывающую, что она должна быть разрешена из кэша клиента Apollo или локальной функции распознавателя.

Теперь давайте посмотрим, как мы можем обновить состояние приложения на простом примере

import React from "react"
import { useMutation, useQuery } from "@apollo/react-hooks";
import gql from "graphql-tag";
const toggleAppTheme = gql`
 mutation updateAppState{
     isDarkModeEnabled
 }
`;

const getAppState = gql`
   query {
       state @client {
           appState {
             isDarkModeEnabled
           }
       }
   }
`;

const ToggleTheme = () => {
   const { loading, error, data } = useQuery(getAppState)
   const [toggleTheme] = useMutation(toggleAppTheme);

   const handleToggle = () => {
       const { isDarkModeEnabled } = data.state.appState;
       const newAppState = {
           isDarkModeEnabled: !isDarkModeEnabled,
           __typename: 'AppState'
       }
       toggleTheme({variables: newAppState})
   }

   if(loading) {
       return 

Loading...

} return ( ) } export default ToggleTheme;

Это оно! Все компоненты, которые прослушивают локальное состояние, получат обновленное значение для appState и впоследствии повторно выполнят рендеринг после обновления.

#React #GraphQL