Создайте клиентский интерфейс

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

В предыдущей части этой серии блогов мы обсуждали, чем хорош GraphQL и как он может помочь нам минимизировать загружаемые данные и сделать их минимальными, запрашивая только те данные, которые нам нужны. Давайте начнем создавать легкий интерфейс и посмотрим, как мы можем использовать Apollo Client, чтобы сделать наше приложение React более эффективным.

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

Здесь мы собираемся использовать create-react-app для создания нашего стартового кода. create-react-app - отличный способ начать с настройки проекта React. Он создается и поддерживается командой React, поэтому мы можем ожидать первоклассной конфигурации для нашего приложения React. Вы можете проверить create-react-app на GitHub.

Теперь у нас есть базовый стартовый код React, давайте начнем с добавления нашей зависимости Apollo Client.

  • apollo-boost: Пакет, содержащий все необходимое для установки Apollo Client
  • @apollo/react-hooks: Интеграция уровня представления на основе React Hooks
  • graphql: Также анализирует ваши запросы GraphQL

Поскольку мы закончили добавлять наши основные зависимости, теперь мы начинаем с настройки нашего клиента Apollo для взаимодействия с нашим сервером. Начнем с создания нашего apollo-client.js файла.

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

Клиент предоставляет нам доступ ко многим методам, но в основном мы собираемся использовать два из них: mutate и query.

Как ясно из названия, mutate используется для выполнения мутаций на нашем сервере. У нас есть доступ и к другим методам, например localState. Apollo Client также помогает нам поддерживать состояние нашего приложения React, поэтому нам не нужен Redux или какой-либо другой пакет управления состоянием. У нас также есть доступ к встроенному кэшированию с помощью пакета Apollo Client.

Нам нужно позволить нашему приложению React получить доступ к данным, которые наш клиент может использовать для создания интерфейсов. Для этого нам нужно обернуть все наше приложение, используя ApolloProvider. ApolloProvider похож на Context.Provider в React. Если вы раньше использовали React, возможно, вы знаете о React Context. Он обертывает ваше приложение React и помещает клиента в контекст, что позволяет вам получить к нему доступ из любого места в дереве компонентов. В App.js давайте обернем наше приложение React ApolloProvider.

Теперь, когда мы обернули все наше приложение ApolloProvide, мы можем выполнить Query и Mutation в любом месте нашего приложения и получить доступ к данным. Посмотрим, как это сделать. Давайте создадим новый файл для наших задач и один файл, в который мы будем писать все наши запросы.

Поскольку мы настроили наш клиент Apollo и обернули все наше приложение с помощью ApolloProvider, мы можем начать запрашивать данные с помощью useQuery Hook. useQuery - это Hook, экспортированный из @apollo/react-hooks, который использует Hooks API для обмена данными GraphQL с вашим пользовательским интерфейсом. Так что давайте перейдем к делу.

Во-первых, давайте создадим наш запрос GraphQL, заключенный в функцию gql.

Теперь мы можем использовать эти запросы в useQuery Hook. Когда наш компонент отрисовывается и запускается useQuery Hook, будет возвращен объект результата, содержащий свойства loading, error и data. Клиент Apollo отслеживает для нас ошибки и состояние загрузки, что будет отражено в свойствах loading и error. Как только результат нашего запроса вернется, он будет прикреплен к свойству data. Мы можем обрабатывать все состояния приложения из object, которые мы получаем обратно из нашего useQuery Hook.

Давайте создадим наш первый компонент с useQuery Hook и получим наши задачи.

Теперь нам просто нужно добавить наш недавно добавленный компонент в наш App.js, чтобы мы могли увидеть результат. Давайте сделаем это.

Давайте запустим наши серверные и интерфейсные сервисы и посмотрим на результат.

Перейдем к http://localhost:3000/ и посмотрим, как выглядит наше приложение.

Это не очень хорошо выглядит, но идею вы поняли. Мы настроили Apollo Client и можем получать наши данные из базы данных. Но у нас есть одна небольшая проблема. На первой странице мы перегрузили. Мы просто используем имя задачи, но получаем все id, независимо от того, выполнены они или нет. Это не хорошо.

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

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

После этого, если мы вернемся к нашему приложению, мы увидим, что ничего не изменилось. В этом сила GraphQL. Вы можете просто запросить данные, которые вы используете, и сэкономить на некоторой пропускной способности сети.

А теперь двинемся вперед. Нашим вторым запросом будет Mutation, чтобы добавить данные в нашу внутреннюю службу. Давайте создадим новый компонент внутри нашей папки src, чтобы добавить задачи в нашу серверную часть.

Мы создали наш компонент для создания Task в нашей бэкэнд. Давайте добавим его в наш App.js файл и посмотрим, как он будет выглядеть.

Теперь мы видим наш новый компонент. Давайте добавим несколько задач и посмотрим, работает ли это. Мы добавляем новую задачу под названием «Добавить новую задачу», но только после обновления страницы, потому что именно тогда происходит повторная выборка данных. Мы можем легко это исправить, но мы должны быть счастливы, потому что теперь мы можем взаимодействовать как с запросами, так и с изменениями в серверной службе. Мы можем сделать это очень эффективно, запрашивая только те данные, которые нам нужны для нашей интерфейсной службы.

Повторная загрузка

Еще один действительно полезный метод, который дает нам Apollo Client, называется refetch. Как следует из названия, мы можем снова получить некоторые данные, если считаем, что данные могли быть обновлены. Посмотрим, как мы можем использовать этот метод. Чтобы использовать его, нам, возможно, придется провести некоторый рефакторинг кода. Но сначала давайте посмотрим, где живет этот метод.

Где бы мы ни использовали useQuery, мы получаем доступ к методу refetch. Повторная выборка позволяет обновлять результаты запроса в ответ на определенное действие. В нашем случае мы можем использовать метод refetch для получения дополнительных задач всякий раз, когда мы добавляем нашу новую задачу. Итак, давайте проведем некоторый рефакторинг и переместим состояние на один уровень выше, чтобы мы могли передать этот метод AddTask компоненту, чтобы он мог его использовать. Давайте создадим еще один компонент с именем TaskContainer и переместим в него наши компоненты AddTask и Task.

Теперь мы переместили состояние Task компонента на уровень выше и можем передать это состояние как props нашему Task компоненту.

Наш компонент задачи остался неизменным, за исключением того, что теперь вместо локального состояния у нас есть состояние, исходящее от props. В нашем App.js файле нам просто нужно импортировать недавно созданный компонент, и мы почти закончили рефакторинг.

Посмотрим, как мы можем использовать наш refetch метод. Как вы знаете, мы передали этот метод компоненту AddTask, поэтому у нас есть доступ к этому методу через props. Заглянем в наш AddTask.js файл и посмотрим, что мы хотим сделать. Мы хотим обновлять все наши задачи всякий раз, когда мы добавляем новую задачу, поэтому мы можем добавить метод refetch в наш onSubmit call после того, как мы успешно добавили нашу новую задачу. Посмотрим, как это выглядит.

Опрос

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

Помимо refetch, мы также получаем опрос, в котором мы можем указать, через сколько интервалов времени мы хотим, чтобы конкретный запрос запускался и извлекал данные из серверной службы. Опрос обеспечивает синхронизацию с вашим сервером почти в реальном времени, заставляя запрос выполняться периодически с заданным интервалом. Давайте посмотрим на небольшой пример опроса.

Если указать для опроса 500, мы будем получать задачи каждые 0,5 секунды из нашей серверной службы. Эти небольшие методы могут быть полезны в некоторых ситуациях, и их полезно иметь при себе.

Политика получения

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

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

Заключение

Создание приложения с помощью GraphQL может дать вам много преимуществ. Для этого существует множество отличных библиотек, но на данный момент Apollo Client является одним из лучших и дает вам множество полезных методов, которые могут реально помочь в некоторых сценариях. Создание ваших сервисов с помощью GraphQL может дать вам много преимуществ, например, сэкономить на пропускной способности. У клиента больше контроля над данными, включая то, какие данные ему нужны, какие данные полезны для создания определенных компонентов, а какие нет.