Автор материала, перевод которого мы публикуем сегодня, говорит, что миссия разработчиков Apollo Client заключается в том, чтобы сделать этот инструмент самым современным и удобным решением для управления состоянием React-приложений. Сообщество React развивается и осваивает новые эффективные способы разработки пользовательских интерфейсов. Создатели Apollo Client стремятся к тому, чтобы их проект поддерживал бы всё самое актуальное из мира React. Следуя этой традиции, разработчики Apollo Client представляют новую версию системы, оснащённую поддержкой хуков React.
Хуки были представлены в React 16.8. Это — новый механизм, позволяющий создавать компоненты, обладающие состоянием, и при этом не сталкиваться с проблемами, характерными для компонентов, основанных на классах. Сейчас Apollo Client включает в себя три хука, которые можно использовать в приложениях — во всех тех местах, где используются компоненты высшего порядка или механизмы render props. Речь идёт о хуках useQuery
, useMutation
и useSubscription
. Эти хуки просты в освоении, они обладают множеством преимуществ перед ранее существовавшим API. В частности, это касается уменьшения размеров бандла приложения и сокращение объёма шаблонного кода.
Начало работы
Если вы собираетесь создать новый Apollo-проект — мы рекомендуем установить следующий пакет после того, как вы настроили свой экземпляр Apollo Client:
npm install @apollo/react-hooks
Этот пакет экспортирует компонент ApolloProvider
, использующийся для подключения Apollo Client к React-приложению. По такой же схеме работа была организована и с использованием старого API.
Если у вас уже есть проект, в котором используется Apollo, это значит, что у вас имеется несколько способов по переходу на хуки. Выбор конкретного способа зависит от того, как именно вы хотите совершить переход. Подробности об этом можно найти здесь.
Почему хуки — это будущее?
Apollo Client всё ещё поддерживает API, основанные на компонентах высшего порядка и на render props. Эти API будут присутствовать в системе ещё некоторое время. Мы полагаем, что в будущем хуки окажутся наилучшим механизмом загрузки данных с помощью Apollo Client. Хотя тем, кто уже пользуется Apollo, необязательно прямо сейчас переходить на хуки, им стоит использовать хуки для новых компонентов. У этой рекомендации есть несколько причин, которые мы сейчас рассмотрим.
▍При использовании хуков нужно меньше кода, используемого для работы с данными
Хуки уменьшают объёмы шаблонного кода, используемого для работы с данными. Это ведёт к сокращению размеров компонентов и к тому, что в подобных компонентах оказывается легче разобраться. В результате разработчикам больше не понадобится вникать в то, как устроены компоненты высшего порядка, или анализировать сложную логику механизмов render props. Для загрузки данных достаточно вызывать единственную функцию useQuery
:
const LAST_LAUNCH = gql`
query lastLaunch {
launch {
id
timestamp
}
}
`;
export function LastLaunch() {
const { loading, data } = useQuery(LAST_LAUNCH);
return (
<div>
<h1>Last Launch</h1>
{loading ? <p>Loading</p> : <p>Timestamp: {data.launch.timestamp}</p>}
</div>
);
}
Здесь показана загрузка данных с помощью хука Apollo Client useQuery
Взгляните на это учебное приложение, в котором можно увидеть работающий пример использования хуков Apollo Client.
▍Множественные мутации
Когда вы выполняете множественные мутации в одном компоненте, использование компонентов высшего порядка или механизма render props может привести к появлению кода, который сложно будет понять. Применение API render prop, построение конструкций, состоящих из вложенных друг в друга компонентов Mutation
, даёт ложное ощущение структурированности кода и его чёткой иерархии. Новый хук useMutation
позволяет полностью обойти эту проблему. Дело в том, что его использование сводится к простому вызову функции. В следующем примере показано то, как несколько мутаций и запросов могут друг с другом взаимодействовать. Всё это происходит в пределах одного и того же компонента:
function Message() {
const [saveMessage, { loading }] = useMutation(SAVE_MESSAGE);
const [deleteMessage] = useMutation(DELETE_MESSAGE);
const { data } = useQuery(GET_MESSAGE);
return (
<div>
<p>
{loading
? 'Loading ...'
: `Message: ${data && data.message ? data.message.content : ''}`}
</p>
<p>
<button onClick={() => saveMessage()}>Save</button>
<button onClick={() => deleteMessage()}>Delete</button>
</p>
</div>
);
}
Здесь используется хук useMutation
. Увидеть множественные мутации в действии можно здесь. Это приложение-пример, кроме того, содержит похожий компонент, созданный с помощью render props. Это даёт вам возможность сравнить данный компонент с тем, который создан с использованием хуков.
▍Улучшенная поддержка TypeScript
Ни для кого не секрет то, что мы — большие фанаты TypeScript. Возможности новых хуков отлично сочетаются с автоматическими определениями типов, генерируемыми с помощью Apollo CLI. Это значительно облегчает написание типобезопасного кода React-компонентов. Вот как выглядит загрузка данных с использованием хука useQuery
и TypeScript:
import { RocketData, RocketVars } from './types';
const GET_ROCKET_INVENTORY = gql`
query getRocketInventory($year: Int!) {
rocketInventory(year: $year) {
id
year
}
}
`;
export function RocketInventoryList() {
const { loading, data } = useQuery<RocketData, RocketVars>(
GET_ROCKET_INVENTORY,
{ variables: { year: 2019 } }
);
return (/* ... show data ... */);
}
Хуки Apollo и TypeScript облегчают разработку строго типизированных компонентов React.
Дополнительные улучшения Apollo Client для React-разработчиков
Хотя в этом релизе Apollo основное внимание уделяется новым хукам, мы можем рассказать и о ещё некоторых интересных новых возможностях.
▍Уменьшение размеров бандла на 50%
В то время как размер минифицированного и сжатого gzip пакета react-apollo@2
составляет 10.6 Кб, размер пакета react-apollo@3
оказывается равным лишь 7.8 Кб. Более того, если вам достаточно пакета @apollo/react-hooks
, то размер бандла уменьшается до всего 5.1 Кб. Это даёт 50% экономию по сравнению с react-apollo@2
.
▍Отложенное выполнение запросов
Хук useQuery
выполняет свой запрос в момент вызова функции. Но именно такое поведение системы нужно не всегда. Представьте себе, например, поле для ввода поискового запроса, выдающее пользователю подсказки. Вам может понадобиться вывести компонент с таким полем, готовым принять то, что введёт пользователь. Но при этом выполнение запроса к поисковому серверу будет отложено до того момента, когда пользователь начнём что-то в поле вводить. Для реализации подобного сценария можно воспользоваться хуком useLazyQuery
, который возвращает кортеж с функцией execute
во второй позиции:
const [execute, { loading, data }] = useLazyQuery(GET_INVENTORY);
Запрос не будет выполнен до тех пор, пока вы не вызовете функцию execute
. В этот момент компонент повторно отрендерится и будет применена обычная схема выполнения запросов, реализуемая с помощью useQuery
.
▍Новая документация по API
Мы обновили документацию по Apollo Client, добавив туда сведения о хуках. Именно их мы рекомендуем использовать тем, кто только начал работу с нашей системой. Правда, несмотря на это, мы не убирали из документации сведения о том, как работать с компонентами высшего порядка и с механизмом render props. В примерах кода, которые можно найти в документации, теперь можно воспользоваться новым выпадающим меню, позволяющим переключаться между кодом, демонстрирующим решение одной и той же задачи с использованием подхода, который больше всего нравится читателю.
Различные варианты кода, доступные в документации
Итоги
Создатели Apollo Client говорят, что в React им больше всего нравится то, что основная команда разработчиков этой библиотеки и сложившееся вокруг неё сообщество энтузиастов постоянно стремятся к улучшению удобства работы с React с точки зрения программиста. Появление хуков, попробовать которые рекомендуется абсолютно всем, представляет собой один из ярких примеров подобного стремления.
Надеемся, что хуки React, появившиеся в Apollo Client, понравятся тем, кто применяет этот проект при разработке своих приложений.
Уважаемые читатели! Пользуетесь ли вы Apollo Client?
Автор: ru_vds