Если вы хотите создать приложения с React и GraphQL, Apollo – это библиотека, которую вы должны использовать.
Я собрал всеобъемлющую Chechseet, которая проходит все основные концепции в библиотеке APOLLO, показывая вам, как использовать его с помощью реакции с фронта до спины.
Хотите вашу собственную копию? ?
Вы можете взять PDF Chechseet Прямо здесь (Это занимает 5 секунд).
Вот несколько быстрых побед от захвата загружаемой версии:
- ✓ Быстрая ссылка на рассмотрение, однако, когда
- ✓ Тонны полезных фрагментов кода, основанные на реальных проектах
- ✓ Прочитайте это руководство в автономном режиме, где вам нравится. На поезде, на вашем столе, стоя в очереди – где угодно.
Предпочитаю видео уроки? ?
Большая часть этой Chechseet основана на приложении, построенном в React + GraphQl 2020 Carch Cound Course.
Если вы хотите еще несколько рук на видео уроки, плюс см. Как создавать приложения с React, GraphQL и APOLLO, вы можете посмотреть курс прямо здесь Отказ
ПРИМЕЧАНИЕ: эта читчик предложит знакомство с React и GraphQL. Если вам нужен быстрый переподготовки на график и как его написать, отличный ресурс – это Официальный сайт graphql Отказ
Оглавление
Начиная
- Что такое Аполлон и почему нам это нужно?
- Настройка клиента Apollo
- Создание нового клиента Apollo
- Предоставление клиента реагировать на компоненты
- Использование клиента напрямую
- Написание graphql в файлах .js с gql
Core Apollo React Cloots
- Приобретение использует крючок
- UselazyQuery Крюк
- USEMUTTION КУРС
- Подсказка к применению
Основные рецепты
- Вручную установленную политику Fetch
- Обновление кеша на мутации
- Пояснение запросов с использованием использования
- Пояснение запросов с помощью USEMution
- Доступ к клиенту с UseAppollocLient
Что такое Аполлон и почему нам это нужно?
Apollo – это библиотека, объединяющая две невероятно полезные технологии, используемые для создания веб-и мобильных приложений: React и GraphQL.
Реагирование было сделано для создания отличного пользовательского опыта с помощью JavaScript. GraphQL – это очень простой и декларативный новый язык для легкого и эффективной выборки и изменения данных, будь то из базы данных или даже из статических файлов.
APOLLO – это клей, который связывает эти два инструмента вместе. Кроме того, он делает работу с React и Graphql намного проще, давая нам много пользовательских реактивных крюков и функций, которые позволяют нам оба операции GraphQQL записать и выполнять их с помощью кода JavaScript.
Мы подробно опишем эти функции на протяжении всего этого руководства.
Apollo Client Основная настройка
Если вы запускаете проект с шаблоном React Template, как Create App App, вам нужно будет установить следующее в качестве базовых зависимостей, чтобы встать и работать с клиентом Apollo:
// with npm: npm i @apollo/react-hooks apollo-boost graphql // with yarn: yarn add @apollo/react-hooks apollo-boost graphql
@ Apollo/React-Cooks дает нам реагированные крюки, которые делают выполнение наших операций и лучше работать с клиентом Apollo
Apollo-Boost помогает нам настроить клиент вместе с анализом наших операций GraphQL
graphql Также заботится о разборке операций GraphQL (наряду с GQL)
Клиент Apollo + настройка подписок
Чтобы использовать все способом операций GraphQL (запросы, мутации и подписки), нам нужно установить более конкретные зависимости по сравнению с простой Apollo-Boost :
// with npm: npm i @apollo/react-hooks apollo-client graphql graphql-tag apollo-cache-inmemory apollo-link-ws // with yarn: yarn add @apollo/react-hooks apollo-client graphql graphql-tag apollo-cache-inmemory apollo-link-ws
Apollo-Client Дает нам клиент напрямую, а не из Apollo-Boost
graphql-tag интегрирован в Apollo-Boost , но не включен в Аполлон-клиент
Apollo-Cache-inMemory Для настройки нашего собственного кеша (который Apollo-Boost , по сравнению, автоматически)
APOLLO-LINK-WS нужен для связи над веб-сайтами, какие подписки требуют
Создание нового клиента Apollo (базовая настройка)
Наиболее простыми настройками для создания клиента APOLLO является созданием нового клиента и предоставления только URI Собственность, которая будет вашей конечной точкой GraphQL:
import ApolloClient from "apollo-boost";
const client = new ApolloClient({
uri: "https://your-graphql-endpoint.com/api/graphql",
});
Apollo-Boost был разработан для того, чтобы делать вещи, такие как создание клиента APOLLO как можно проще. Однако то, что ему не хватает времени, является поддержка подписки GraphQL по подключению WebStocket.
По умолчанию он выполняет операции над HTTP-соединением (поскольку вы можете видеть через наш предоставленный URI выше).
Короче говоря, используйте Apollo-Boost Чтобы создать свой клиент, если вам нужно только выполнять запросы и мутации в вашем приложении.
Он устанавливает кэш памяти по умолчанию, который полезен для хранения наших данных приложения локально. Мы можем прочитать и запись в наш кэш, чтобы предотвратить выполнение наших запросов после обновления наших данных. Мы покроем, как сделать это немного позже.
Создание нового клиента Apollo (+ настройка подписок)
Подписки полезны для легкого отображения результата изменений данных (через мутации) в нашем приложении.
Вообще говоря, мы используем подписки в качестве улучшенного вида запроса. Подписки Используйте подключение WebSocket для «Подписаться» к обновлениям и данным, что включает новые или обновленные данные, которые будут немедленно отображаться нашим пользователям без необходимости перезарядки запросов или обновлять кеш.
import ApolloClient from "apollo-client";
import { WebSocketLink } from "apollo-link-ws";
import { InMemoryCache } from "apollo-cache-inmemory";
const client = new ApolloClient({
link: new WebSocketLink({
uri: "wss://your-graphql-endpoint.com/v1/graphql",
options: {
reconnect: true,
connectionParams: {
headers: {
Authorization: "Bearer yourauthtoken",
},
},
},
}),
cache: new InMemoryCache(),
});
Предоставление клиента реагировать на компоненты
После создания нового клиента передача его ко всем компонентам важно для того, чтобы иметь возможность использовать его внутри наших компонентов для выполнения всех доступных операций GraphQL.
Клиенту предоставляется всем валом компонента с использованием контекста RACT, но вместо того, чтобы создавать наш собственный контекст, мы импортируем специальный поставщик контекста из @ Apollo/React-Cooks называется Аполлопровидер Отказ Мы можем видеть, как он отличается от обычного контекста Ractex из-за того, что он имеет специальный опорой, клиент Специально сделан, чтобы принять созданный клиент.
Обратите внимание, что все эта настройка должна быть сделана в вашем файле index.js или app.js (везде, где объявленные ваши маршруты), чтобы поставщик можно обернуть все ваши компоненты.
import { ApolloProvider } from "@apollo/react-hooks";
const rootElement = document.getElementById("root");
ReactDOM.render(
,
rootElement
);
Использование клиента напрямую
Клиент APOLLO является наиболее важной частью библиотеки из-за того, что она отвечает за выполнение всех операций GraphQL, которые мы хотим выполнить с помощью реагирования.
Мы можем использовать созданный клиент непосредственно для выполнения любой операции, которую нам нравится. Он имеет методы, соответствующие запросам ( Client.Query () ), мутации ( Client.mutate () ) и подписки ( Client.subscribe () ).
Каждый метод принимает объект и его собственные соответствующие свойства:
// executing queries
client
.query({
query: GET_POSTS,
variables: { limit: 5 },
})
.then((response) => console.log(response.data))
.catch((err) => console.error(err));
// executing mutations
client
.mutate({
mutation: CREATE_POST,
variables: { title: "Hello", body: "World" },
})
.then((response) => console.log(response.data))
.catch((err) => console.error(err));
// executing subscriptions
client
.subscribe({
subscription: GET_POST,
variables: { id: "8883346c-6dc3-4753-95da-0cc0df750721" },
})
.then((response) => console.log(response.data))
.catch((err) => console.error(err));
Использование клиента напрямую может быть немного сложно, однако, поскольку при проведении запроса он возвращает обещание. Чтобы разрешить каждое обещание, нам либо нужно .тогда () и .catch () обратные вызовы, как указано выше или на ждать каждое обещание в рамках функции, объявленной с async ключевое слово.
Написание операций GraphQL в файлах .js (GQL)
Уведомление выше, что я не указывал содержимое переменных Get_posts. , Create_post и Get_post. .
Это операции, написанные в синтаксисе GraphQL, которые указывают, как выполнить запрос, мутацию и подписку соответственно. Это то, что мы пишем в любой консоли Graphiql для получения и изменения данных.
Этот вопрос здесь, однако, в том, что мы не можем написать и выполнять инструкции GraphQL в файлах JavaScript (.js), подобные нашему оперативному коду.
Чтобы разбирать операции GraphQL, мы используем специальную функцию, называемую с меткой шаблон литералом, чтобы позволить нам выразить их как строки JavaScript. Эта функция называется GQL Отказ
// if using apollo-boost
import { gql } from "apollo-boost";
// else, you can use a dedicated package graphql-tag
import gql from "graphql-tag";
// query
const GET_POSTS = gql`
query GetPosts($limit: Int) {
posts(limit: $limit) {
id
body
title
createdAt
}
}
`;
// mutation
const CREATE_POST = gql`
mutation CreatePost($title: String!, $body: String!) {
insert_posts(objects: { title: $title, body: $body }) {
affected_rows
}
}
`;
// subscription
const GET_POST = gql`
subscription GetPost($id: uuid!) {
posts(where: { id: { _eq: $id } }) {
id
body
title
createdAt
}
}
`;
Приобретение использует крючок
Использование Крюк, возможно, самый удобный способ выполнения запроса GraphQL, учитывая, что он не возвращает обещание, которое необходимо решить.
Он называется в верхней части любого функционального компонента (поскольку все крючки должны быть) и получает в качестве первого необходимого аргумента – запрос с помощью добыча .
Лучше всего использовать, когда у вас есть вопросы, которые должны быть выполнены немедленно, когда компонент отображается, например, список данных, которые пользователь хотел бы увидеть немедленно, когда страница загружает.
Использование Возвращает объект, из которого мы можем легко разрушить значения, которые нам нужны. После выполнения запроса есть три первичных значения, необходимо использовать в каждом компоненте, в котором мы принесем данные. Они Загрузка , Ошибка . и данные Отказ
const GET_POSTS = gql`
query GetPosts($limit: Int) {
posts(limit: $limit) {
id
body
title
createdAt
}
}
`;
function App() {
const { loading, error, data } = useQuery(GET_POSTS, {
variables: { limit: 5 },
});
if (loading) return Loading...;
if (error) return Error!;
return data.posts.map((post) => );
}
Прежде чем мы сможем отобразить данные, которые мы выбираем, нам нужно обрабатывать, когда мы загружаемся (когда loading установлено значение true), и мы пытаемся получить данные.
В этот момент мы отображаем Div с текстом «Loading» или загрузка спиннера. Нам также необходимо обрабатывать вероятность того, что в получении нашего запроса есть ошибка, например, ошибка сети или если мы ошиблись в написании нашего запроса (ошибка синтаксиса).
Как только мы закончим загрузку, и нет ошибок, мы можем использовать наши данные в нашем компоненте, обычно для отображения наших пользователей (так как мы находимся в примере выше).
Есть и другие значения, которые мы можем разрушать от объекта, который Использование Возвращает, но вам понадобится Загрузка , Ошибка . и данные практически на каждом компонент, где вы выполняете используемый . Вы можете увидеть полный список всех данных, которые мы можем вернуться от UseQuery здесь Отказ
UselazyQuery Крюк
UselazyQuery Крюк обеспечивает другой способ выполнить запрос, который предназначен для выполнения в некотором времени после того, как компонент отображается или в ответ на заданные изменения данных.
UselazyQuery Очень полезно для вещей, которые происходят в любой неизвестной момент времени, например, в ответ на операцию поиска пользователя.
function Search() {
const [query, setQuery] = React.useState("");
const [searchPosts, { data }] = useLazyQuery(SEARCH_POSTS, {
variables: { query: `%${query}%` },
});
const [results, setResults] = React.useState([]);
React.useEffect(() => {
if (!query) return;
// function for executing query doesn't return a promise
searchPosts();
if (data) {
setResults(data.posts);
}
}, [query, data, searchPosts]);
if (called && loading) return Loading...;
return results.map((result) => (
));
}
UselazyQuery отличается от Использование Во-первых, в том, что вернулось с крючка. Это возвращает массив, который мы можем разрушать, вместо объекта.
Поскольку мы хотим выполнить этот запрос когда-нибудь после установки компонента, первый элемент, который мы можем разрушать, является функцией, которую вы можете позвонить, чтобы выполнить этот запрос при выборе. Эта функция запроса называется Поиск поиска в примере выше.
Второе разрушенное значение в массиве является объектом, который мы можем использовать деструктурирование объекта, и из которых мы можем получить все то же самое Свойства, как мы сделали из Использование такие как Загрузка , ошибка и данные Отказ
Мы также получаем важную собственность по имени называется , Что говорит нам, если мы фактически называли эту функцию для выполнения нашего запроса. В этом случае, если называется правда и Загрузка правда, мы хотим Верните «Loading …» вместо наших фактических данных, потому что ждут, когда данные будут возвращены. Вот как UselazyQuery обрабатывает получение данных в синхронном пути без каких-либо обещаний.
Обратите внимание, что мы снова передаем любые необходимые переменные для операции запроса в качестве свойства, переменных ко второму аргументу. Однако, если нам нужно, мы можем пройти эти переменные на объекте, предоставляемом саму функцию запроса.
USEMUTTION КУРС
Теперь, когда мы знаем, как выполнять ленивые запросы, мы точно знаем, как работать с Успедание крюк.
Как UselazyQuery Крючок, он возвращает массив, который мы можем разрушать в ее два элемента. В первом элементе мы вернемся к функции, которая в этом случае мы можем назвать его для выполнения нашей операции мутации. Для следующего элемента мы снова можем разрушать объект, который возвращается нам Загрузка , Ошибка . и данные Отказ
import { useMutation } from "@apollo/react-hooks";
import { gql } from "apollo-boost";
const CREATE_POST = gql`
mutation CreatePost($title: String!, $body: String!) {
insert_posts(objects: { body: $body, title: $title }) {
affected_rows
}
}
`;
function NewPost() {
const [title, setTitle] = React.useState("");
const [body, setBody] = React.useState("");
const [createPost, { loading, error }] = useMutation(CREATE_POST);
function handleCreatePost(event) {
event.preventDefault();
// the mutate function also doesn't return a promise
createPost({ variables: { title, body } });
}
return (
New Post
);
}
Однако в отличие от запросов, мы не используем Загрузка или Ошибка . Для того, чтобы условно что-то сделать. Обычно мы используем Загрузка В таких ситуациях, как когда мы отправляем форму, чтобы предотвратить его представление, чтобы не было, чтобы не выполнить одну и ту же мутацию, ненужденную (как вы можете видеть в примере выше).
Мы используем Ошибка . Для отображения того, что идет не так с нашей мутацией нашим пользователям. Если например, некоторые необходимые значения для нашей мутации не предусмотрены, мы можем легко использовать эти данные об ошибках для условно визуализации сообщения об ошибке на странице, чтобы пользователь мог надеяться, что это может исправить, что идет не так.
По сравнению с прохождением переменных ко второму аргументу Успедание , мы можем получить доступ к пару полезных обратных вызовов, когда определенные вещи имеют место, например, когда мутация завершена и когда есть ошибка. Эти обратные вызовы называются ополнен и OneRror Отказ
ополнен Callback дает нам доступ к возвращенным данным мутации, и очень полезно сделать что-то, когда мутация выполняется, например, идет на другую страницу. OneRror Callback дает нам возвращенную ошибку, когда возникает проблема с мутацией и дает нам другие шаблоны для обработки наших ошибок.
const [createPost, { loading, error }] = useMutation(CREATE_POST, {
onCompleted: (data) => console.log("Data from mutation", data),
onError: (error) => console.error("Error creating a post", error),
});
Подсказка к применению
Крючок с использованием INSEUBSCRICKPORT работает так же, как крюк использования.
INSEBUBSCRICE Возвращает объект, который мы можем разрушать, что включает в себя те же свойства, загрузку, данные и ошибки.
Он выполняет нашу подписку немедленно, когда компонент отображается. Это означает, что нам нужно справиться с загрузкой и состояниями ошибок и только после этого отображать/использовать наши данные.
import { useSubscription } from "@apollo/react-hooks";
import gql from "graphql-tag";
const GET_POST = gql`
subscription GetPost($id: uuid!) {
posts(where: { id: { _eq: $id } }) {
id
body
title
createdAt
}
}
`;
// where id comes from route params -> /post/:id
function PostPage({ id }) {
const { loading, error, data } = useSubscription(GET_POST, {
variables: { id },
// shouldResubscribe: true (default: false)
// onSubscriptionData: data => console.log('new data', data)
// fetchPolicy: 'network-only' (default: 'cache-first')
});
if (loading) return Loading...;
if (error) return Error!;
const post = data.posts[0];
return (
{post.title}
{post.body}
);
}
Как и usequery, UselazyQuery и Usemution, INSERTUBSCRICE принимает Переменные как имущество, предусмотренное на втором аргументе.
Это также принимает, однако, некоторые полезные свойства, такие как Подписаться Отказ Это логическое значение, которое позволит нашу подписку автоматически повторно повторно описать подписку, когда наши реквизиты меняются. Это полезно для того, чтобы когда мы проходим переменные для нашей подписки подписчики, которые мы знаем, изменится.
Кроме того, у нас вызывается функция обратного вызова OnsubscriptionData , что позволяет нам вызвать функцию всякий раз, когда подписные крюки получает новые данные. Наконец, мы можем установить FetchPolicy , что по умолчанию для «кэш-первого».
Вручную установленную политику Fetch
Что может быть очень полезно в отношении APOLLO заключается в том, что он поставляется со своим собственным кешем, который он использует для управления данными, которые мы запрашиваем с нашей конечной точки GraphQL.
Иногда, однако, мы обнаруживаем, что из-за этого кэша вещи не обновляются в интерфейсе UI так, как мы хотим.
Во многих случаях мы не так, как в примере ниже, где мы редактируем сообщение на странице редактирования, а затем после редактирования нашего поста мы ориентируемся на домашнюю страницу, чтобы увидеть его в списке всех сообщений, но мы Смотрите старые данные вместо этого:
// route: /edit/:postId
function EditPost({ id }) {
const { loading, data } = useQuery(GET_POST, { variables: { id } });
const [title, setTitle] = React.useState(loading ? data?.posts[0].title : "");
const [body, setBody] = React.useState(loading ? data?.posts[0].body : "");
const [updatePost] = useMutation(UPDATE_POST, {
// after updating the post, we go to the home page
onCompleted: () => history.push("/"),
});
function handleUpdatePost(event) {
event.preventDefault();
updatePost({ variables: { title, body, id } });
}
return (
);
}
// route: / (homepage)
function App() {
const { loading, error, data } = useQuery(GET_POSTS, {
variables: { limit: 5 },
});
if (loading) return Это не только благодаря кэше Apollo, но и инструкциям для каких данных запросы должны получить. Мы можем изменить, как запрос выходит, используя FetchPolicy имущество.
По умолчанию FetchPolicy установлен на «кэш-первый». Это попытается посмотреть на кеш, чтобы получить наши данные вместо того, чтобы получить его из сети.
Простой способ исправить эту проблему не видеть новых данных – это изменить политику Fetch. Тем не менее, этот подход не идеален с точки зрения производительности, потому что она требует внесения дополнительного запроса (используя кэш непосредственно, потому что это локальные данные).
Существует много разных вариантов для политики FECT, перечисленные ниже:
{
fetchPolicy: "cache-first"; // default
/*
cache-and-network
cache-first
cache-only
network-only
no-cache
standby
*/
}
Я не пойду в то, что делает каждую политику, но для решения нашей непосредственной проблемы, если вы всегда хотите запрос, чтобы получить последние данные, запросив его из сети, мы устанавливаем FetchPolicy к «сети – сначала».
const { loading, error, data } = useQuery(GET_POSTS, {
variables: { limit: 5 },
fetchPolicy: "network-first"
});
Обновление кеша на мутации
Вместо того чтобы обойти кеш, изменив политику извлечения Использование Давайте попытаемся исправить эту проблему, обновляя кэш вручную.
При выполнении мутации с Успедание Отказ У нас есть доступ к другому обратным вызовам, известным как Обновление Отказ
Обновление Дает нам прямой доступ к кеше, а также данные, которые возвращаются из успешной мутации. Это позволяет нам прочитать данный запрос из кэша, возьмите это новые данные и напишите новые данные в запрос, что затем обновит, что видит пользователь.
Работа с кешем вручную – это сложный процесс, который много людей, как правило, избегает, но очень полезно, потому что он экономит некоторое время и ресурсы, не должен выполнять тот же запрос несколько раз, чтобы обновить кеш вручную.
function EditPost({ id }) {
const [updatePost] = useMutation(UPDATE_POST, {
update: (cache, data) => {
const { posts } = cache.readQuery(GET_POSTS);
const newPost = data.update_posts.returning;
const updatedPosts = posts.map((post) =>
post.id === id ? newPost : post
);
cache.writeQuery({ query: GET_POSTS, data: { posts: updatedPosts } });
},
onCompleted: () => history.push("/"),
});
// ...
}
Сначала мы хотим прочитать запрос и получить предыдущие данные из него. Тогда нам нужно принять новые данные. В этом случае, чтобы найти сообщение с данным идентификатором и заменить его с помощью Ньюпост Данные, в противном случае это будет предыдущие данные, а затем записывать эти данные обратно в тот же запрос, убедившись, что она имеет ту же структуру данных, что и раньше.
После всего этого, всякий раз, когда мы редактируем пост и навигациируются на главную страницу, мы должны увидеть эти новые почтовые данные.
Пояснение запросов с использованием использования
Допустим, мы отображим список сообщений, используя Get_posts запрос и удаляя один из них с Delete_post мутация.
Когда пользователь удаляет сообщение, что мы хотим произойти?
Естественно, мы хотим, чтобы это было удалено из списка, как данные, и что отображается для пользователей. Однако, когда проводится мутация, запрос не знает, что данные изменены.
Есть несколько способов обновления того, что мы видим, но один подход – это выполнить запрос.
Мы можем сделать это, схватив погибший Функция, которую мы можем разрушать от объекта, возвращаемого Использование крючок и передайте его к мутации, который будет выполнен, когда он будет завершен, используя ополнен Функция обратного вызова:
function Posts() {
const { loading, data, refetch } = useQuery(GET_POSTS);
if (loading) return Loading...;
return data.posts.map((post) => (
));
}
function Post({ post, refetch }) {
const [deletePost] = useMutation(DELETE_POST, {
onCompleted: () => refetch(),
});
function handleDeletePost(id) {
if (window.confirm("Are you sure you want to delete this post?")) {
deletePost({ variables: { id } });
}
}
return (
{post.title}
{post.body}
);
}
Пояснение запросов с помощью USEMution
Обратите внимание, что мы также можем использовать Успедание Крюк для переосмысления наших запросов через аргумент, предоставляемый на функцию мутата, называется RefetchQueries Отказ
Он принимает массив запросов, которые мы хотим решить после выполнения мутации. Каждый запросы предоставляются в объекте, так же, как мы предоставим его клиенту.
Вот минимальный пример, чтобы погиб нашего Get_posts Запрос после создания нового поста:
function NewPost() {
const [createPost] = useMutation(CREATE_POST, {
refetchQueries: [
{
query: GET_POSTS,
variables: { limit: 5 }
}
],
});
// ...
}
Использование клиента с UseAppollocLient
Мы можем получить доступ к клиенту по нашим компонентам с помощью специального крючка, называемого клиентом Apollo. Это выполняет крючок в верхней части нашего функционального компонента, и мы вернемся к себе клиента.
function Logout() {
const client = useApolloClient();
// client is the same as what we created with new ApolloClient()
function handleLogout() {
// handle logging out user, then clear stored data
logoutUser();
client.resetStore().then(() => console.log("logged out!"));
/* Be aware that .resetStore() is async */
}
return ;
}
И оттуда мы можем выполнять все те же вопросы, мутации и подписки.
Обратите внимание, что есть тонкие функции, которые поставляются с методами, которые поставляются с клиентом. Используя клиента, мы также можем написать и прочитать данные в кэш и из кэша, которые Apollo настраивает (используя Client.Readdata () и Client.WRITATATA () ).
Работа с кэшем Apollo заслуживает своего собственного курса в по себе. Отличное преимущество работы с APOLLO заключается в том, что мы также можем использовать его в качестве системы управления для замены таких решений, как Redux для нашего глобального государства. Если вы хотите узнать больше о использовании APOLLO, чтобы управлять глобальным приложением, вы можете Проверьте следующую ссылку Отказ
Я попытался сделать эту Chechseet как можно более полной, хотя он все еще оставляет много функций Аполлона, которые стоит расследовать.
Если вы хотите больше о Apollo, обязательно проверьте Официальная документация Apollo Отказ
Скачайте ChechSeet.
Хотите быструю ссылку на все эти концепции?
Нажмите, чтобы схватить полный PDF Chechseet
Оригинал: “https://www.freecodecamp.org/news/react-apollo-client-2020-tutorial/”