DevGang
Авторизоваться

Как создать приложение для Pokemon с помощью GraphQL и Apollo

Pokemon - это японская медиа-франшиза, состоящая из видеоигр, анимационных сериалов и фильмов, карточной игры и других связанных с ней медиа.

В этом блоге мы будем использовать Pokemon GraphQL API, который предоставляет нам данные о разных покемонах.

Мы будем использовать Apollo и GraphQL для обработки выборки данных и React для создания нашего интерфейсного приложения.

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

Предварительные условия

Для дальнейшего использования они должны быть на вашем компьютере:

  1. Nodejs v18+
  2. Редактор кода
  3. Веб-браузер.

Давайте перейдем к созданию нашего приложения React.

Настройка приложения React

Чтобы создать приложение React, перейдите в свой терминал и воспользуйтесь командной строкой. Откройте командную строку и выберите удобное расположение для создания проекта React. Давайте начнем с рабочего стола.

cd Desktop

Приведенная выше команда перейдет на ваш рабочий стол.

npm create vite@latest pokemon-app -- --template react

npm create vite@latest начнет создавать новый проект с использованием Vite. Но мы добавили название нашего проекта (pokemon-app) и технологию или структуру, которую будет использовать наше приложение (-- -- template react).

Вы можете установить другой шаблон, например svelte, vanilla или vue, и проект будет создан с использованием этой структуры. Подробнее о Vite читайте на его официальном сайте.

После установки Vite выполните следующие команды:

cd pokemon-app
npm install
npm run dev

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

Запустите первую команду cd pokemon-app, чтобы перейти к папке pokeman-app.

Запустите code .. чтобы открыть папку в редакторе кода.

модальное отображение через VSCode, подтверждающее, что вы доверяете авторам файлов, открытых в VSCode
модальное отображение через VSCode, подтверждающее, что вы доверяете авторам файлов, открытых в VSCode

Установите флажок «Доверять автору», если он появится.

Откройте терминал редактора кода. Если вы используете VSCode в Windows, ярлык — Ctrl + `.

Запустите две другие команды в терминале одну за другой.

npm install
npm run dev

Сейчас ваш проект должен быть запущен в браузере.

Мы будем управлять получением наших данных с помощью GraphQL и Apollo.

Как использовать GraphQL и Apollo

GraphQL - это язык запросов для API и среда выполнения для выполнения запросов с вашими существующими данными. Он позволяет вам запрашивать только те данные, которые вам нужны в вашем приложении, и ничего больше, что делает его очень эффективным и гибким.

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

Давайте установим нужные вам пакеты.

Установка пакетов

Запустите приведенную ниже команду в своем терминале, чтобы установить клиент Apollo.

npm install @apollo/client

Перейдите к вашему основному main.jsx и импортируйте эти:

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import {
  ApolloProvider,
  ApolloClient,
  InMemoryCache,
} from "@apollo/client";
import "./index.css";

Вы импортировали React и ReactDOM для манипуляций с DOM.

ApolloClient отвечает за выборку данных вашего приложения и управление состоянием. Он обрабатывает отправку запросов и мутаций GraphQL на ваш сервер GraphQL и кэширует результаты.

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

InMemoryCache — это реализация кэша для хранения результатов запросов GraphQL в памяти для эффективного доступа и извлечения.

Вы также импортировали index.css для оформления своего приложения.

Как создать Client Apollo

const client = new ApolloClient({
  uri: "https://graphql-pokemon2.vercel.app/",
  cache: new InMemoryCache(),
});

Приведенный выше код создает новый экземпляр ApolloClient с некоторыми конфигурациями:

  • uri: Здесь указан URL-адрес вашей конечной точки GraphQL API. Это конечная точка, в которую ваш клиент Apollo будет отправлять запросы GraphQL и изменения.
  • cache: Это позволяет клиенту Apollo использовать кэш в памяти для доступа к данным и сохранения результатов запросов GraphQL, что снижает необходимость в повторном извлечении данных с сервера.

Теперь вы можете использовать компонент <App /> в ApolloProvider:

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </React.StrictMode>
);

Обратите внимание, что реквизиты client также были переданы для предоставления вашему приложению конфигурации ApolloClient.

Перейдите к компоненту App.jsx и введите следующее:

import React from "react";
import { PokemonsContainer } from "./components/PokemonsContainer";

export default function App() {
  return (
    <main>
      <PokemonsContainer />
    </main>
  );
}

Вы импортировали React и PokemonsContainer будет создан. Компонент PokemonsContainer был заключен в основной тег и будет отображаться при вставке компонента в DOM.

Давайте создадим компонент PokemonsContainer в файле, расположенном в папке компонентов. То есть:

📂 src/comComponents/PokemonsContainer.jsx

Компонент Pokemon Container

import React from "react";
import { useQuery } from "@apollo/client";
import { Pokemon } from "../components/Pokemon";
import { GET_POKEMONS } from "../graphql/get-pokemons";

UseQuery из @apollo/client используется для выполнения запросов в приложении Apollo. Для этого вызывается метод useQuery() и строка запроса GraphQL передается в качестве аргумента. Когда ваш компонент визуализируется, useQuery возвращает объект из клиента Apollo, который содержит свойства loading, error и data, которые вы можете использовать для визуализации вашего пользовательского интерфейса.

Компонент Pokemon был импортирован для рендеринга пользовательского интерфейса для Pokemon, он будет создан в ближайшее время.

GET_POKEMONS также был импортирован. Он будет содержать запрос GraphQL.

После импорта вышеуказанных функций продолжайте создавать свою страницу.

export function PokemonsContainer() {
  const { loading, error, data } = useQuery(GET_POKEMONS, {
    variables: { first: 5 },
  });

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  const pokemons = data?.pokemons || [];
  return (
    <div className="container">
      {pokemons &&
        pokemons.map((pokemon) => (
          <Pokemon key={pokemon.id} pokemon={pokemon} />
        ))}
    </div>
  );
}

Как упоминалось ранее, useQuery возвращает объект из Apollo Client, который содержит свойства loading, error и data. Здесь они деструктурированы, поэтому вы можете получить к ним доступ на странице.

Обратите внимание, что мы предоставляем параметр конфигурации (variables) для перехватчика useQuery. { variables: { first: 5 } } также были переданы в качестве второго аргумента. Опция variables — это объект, который содержит все переменные, которые мы хотим передать в наш запрос GraphQL. В этом случае мы передали объект { first: 5 }, чтобы указать, что нам нужны первые пять покемонов.

Если запрос все еще загружается, <p>Loading...</p> возвращается для обозначения пользователя, а <p>Error: {error.message}</p> будет возвращен в случае ошибки.

Константа pokemons была создана для хранения значения свойства Pokemons объекта данных. Если data.pokemons недоступен, константа pokemons будет пустым массивом.

div возвращается с classname container, который проверяет, доступен ли pokemons, и сопоставляет массив с компонентом Pokemon.

Давайте создадим компонент Pokemon:

📂src/components/Pokemon.jsx

Компонент Pokemon

import React from "react";

export function Pokemon({ pokemon }) {
  return (
    <div className="pokemon">
      <div className="pokemon__name">
        <p>{pokemon.name}</p>
      </div>
      <div className="pokemon__meta">
        <span>{pokemon.maxHP}</span>
        <span>{pokemon.maxCP}</span>
      </div>
      <div className="pokemon__image">
        <img src={pokemon.image} alt={pokemon.name} />
      </div>
      <div className="pokemon__attacks">
        {pokemon.attacks.special.slice(0, 3).map((attack) => (
          <span key={`${attack.name}-${attack.damage}`}>{attack.name}</span>
        ))}
      </div>
    </div>
  );
}

Здесь определяется структура экземпляра покемона с использованием classname для стилизации. Будут отображены name, maxHP, maxCP, image и массив attack.

Давайте создадим запрос GET_POKEMONS GraphQL.

📂src/graphql/get-pokemons

GraphQL-запрос

import gql from "graphql-tag";

export const GET_POKEMONS = gql`
  query pokemons($first: Int!) {
    pokemons(first: $first) {
      id
      name
      image
      maxHP
      maxCP
      attacks {
        special {
          name
          damage
        }
      }
    }
  }
`;

Вы импортировали gql из graphql-tag и создали запрос GraphQL с именем GET_POKEMONS.

Функция query pokemons была заключена в строки, чтобы функция gql могла анализировать их в документы запроса.

$first: Int! означает, что ваш запрос ожидает переменную, вызываемую first, которая является целым числом, а cимвол ! после Int означает, что переменная обязательна.

Напомним, что мы создали объект variables в компоненте PokemonsContainer, он находится здесь ниже.

 const { loading, error, data } = useQuery(GET_POKEMONS, {
   variables: { first: 5 },
 });

pokemons(first: $first) также был объявлен. Здесь $first будет присвоено значение 5 (в приведенном выше фрагменте кода мы передали значение 9). Таким образом, массив будет содержать всего 5 объектов. Каждый объект будет содержать id, name, image, maxHP, maxCP и объект attacks, который будет содержать специальный объект, содержащий имя и урон.

Сервер GraphQL может содержать больше свойств, но будет возвращать только свойства, перечисленные выше. Это одна из замечательных функций GraqhQL – она предоставляет вам только те данные, которые вы запрашиваете.

Стилизация нашего приложения

Ваш index.css должен содержать это:

/* RESETS
=========================================== */
html {
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

*,
*:before,
*:after {
  -webkit-box-sizing: inherit;
  box-sizing: inherit;
}

body {
  margin: 20px 0;
  padding: 0 20px;
  line-height: 1;
  font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  color: #202020;
  background-color: #fbfbfb;
  font-smooth: always;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* POKEMON APPLICATION
=========================================== */
.container {
  display: flex;
  max-width: 80%;
  margin: auto;
  height: 100vh;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}

.container p {
  margin: 0;
}

.container .pokemon {
  width: 20%;
  background-color: #fff;
  background-clip: border-box;
  border: 1px solid rgba(0, 0, 0, 0.125);
  border-radius: 0.25rem;
  box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
  overflow: hidden;
  /* margin: 5px; */
}

.container .pokemon__name {
  background-color: #ecd018;
  text-align: center;
  padding: 10px;
}

.container .pokemon__name p {
  text-transform: uppercase;
  font-weight: bold;
  color: white;
  letter-spacing: 4px;
  text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.4);
}

.container .pokemon__image {
  padding: 20px;
  min-height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.container .pokemon__image img {
  max-width: 100%;
  height: auto;
}

.container .pokemon__attacks {
  display: flex;
  padding-left: 10px;
  padding-right: 10px;
  justify-content: space-between;
}

.container .pokemon__attacks span {
  width: 32%;
  background-color: #f16820;
  border-radius: 3px;
  padding: 7px;
  font-weight: 700;
  color: #fff;
  padding-left: 10px;
  padding-right: 10px;
  font-size: 12px;
  margin-bottom: 10px;
  word-wrap: break-word;
  text-align: center;
  line-height: 15px;
}

.container .pokemon__meta {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
  padding: 0 10px;
}

.container .pokemon__meta span {
  color: white;
  text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.4);
  background-color: #7bb7b7;
  font-weight: bold;
  margin: 0;
  padding: 5px 20px;
  border-radius: 5px;
}

Если все сделано правильно, в вашем браузере должно быть следующее:

Изображение, показывающее данные пяти покемонов в браузере
Изображение, показывающее данные пяти покемонов в браузере

Вы можете получить код GitHub: https://github.com/segunajibola/pokemon-graphql

Вы также можете просмотреть действующий сайт, размещенный на Vercel: pokemonsapp.vercel.app

Спасибо за внимание!

Источник:

#React #GraphQL
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу