Привет, друзья! В этой статье я хочу поделиться с вами опытом разработки хука для загрузки дополнительных данных (авось кому-нибудь пригодится). На самом деле, хуков будет целых 2 штуки: Первый хук попроще, второй посложнее. Полагаю, лишним будет говорить, что необходимость в использовании подобных хуков возникает в каждом втором проекте (по крайней мере, в моей сфере деятельности). Исходный код проекта. Для запуска проекта в песочнице в терминале необходимо выполнить команду yarn start. Команды для локального запуска проекта: Скриншот страницы, на которой используется хук useLoadPage, для затравки: 
Проект состоит из двух частей: Сервер написан на Node, клиент — на React и TypeScript. Структура проекта: 
Код сервера состоит из 2 файлов: Фиктивные данные представляют собой массив из 100 товаров (allItems). Каждый товар — это примерно такой объект: Товары разделены на 10 страниц (allPages). Каждая страница — это объект, ключом которого является номер страницы, а значением — массив из 10 товаров: После генерации фиктивные данные записываются в файл server/data/fake.json. Сервер обрабатывает запросы к 3 конечным точкам: В целом, это все, что касается сервера. На клиенте у нас имеется следующее: Перейдем непосредственно к рассмотрению хуков. Начнем с более простого — useLoadMore. Импортируем хуки из react и react-router-dom, а также типы для функции получения товаров и объекта товара из types.ts: Типы выглядят так: Определяем тип для объекта, возвращаемого хуком: Как мы видим, хук возвращает следующее: Определяем хук: Определяем переменные для товаров, значения (номера) текущей страницы, всех (доступных) страниц и индикатора загрузки, а также получаем объект истории браузера: Определяем функцию (внутренний метод) для загрузки товаров: Выполняем однократный побочный эффект для загрузки товаров на основе значения текущей страницы: Определяем функцию (публичный интерфейс) для загрузки дополнительных товаров: Зачем мы манипулируем адресом страницы? На это существует, как минимум, 2 причины: Наконец, возвращаем объект: Пример использования этого хука можно увидеть на странице MoreProducts.tsx. При нажатии кнопки 👀 вызывается функция loadMore из хука. Когда индикатор наличия товаров получается значение false, эта кнопка не рендерится. Данный индикатор также можно установить в качестве значения атрибута disabled кнопки. Даже если разблокировать кнопку через редактирование разметки, загрузки несуществующих товаров не произойдет благодаря проверке currentPage.current < allPages.current. Теперь рассмотрим более продвинутый хук — useLoadPage. В начале мы также импортируем хуки и типы: Определяем тип для возвращаемого хуком объекта: Как мы видим, хук возвращает много всего интересного: В дополнение к этому я решил реализовать кеширование загруженных ранее страниц товаров. Определяем тип для соответствующего объекта: Приступаем к реализации хука: Определяем переменные для товаров, кеша, текущей страницы, первой страницы, всех страниц и индикатора загрузки, а также получаем объект истории браузера: Определяем функцию (внутренний метод) для загрузки товаров: Выполняем однократный побочный эффект для загрузки товаров на основе значения текущей страницы: Определяем функцию (публичный интерфейс) для загрузки товаров по номеру страницы: Определяем функции (публичный интерфейс) для загрузки следующей и предыдущей страниц товаров: Наконец, возвращаем объект: Хак с первой страницей нужен для первоначального рендеринга страницы ProductsByPage, когда мы начинаем со второй и далее страницы. Если определить первую страницу явно (т.е. как 1), то индикатор hasPrev получит значение true и мы увидим заблокированную кнопку "Назад" над "лоадером". Попробуйте поэкспериментировать. Возможно, вы найдете лучшее решение. Пример использования данного хука можно увидеть на странице ProductsByPage. Вот для чего используется каждое из возвращаемых хуком значений: На странице ProductsByPage также реализовано переключение между страницами товаров при нажатии стрелок на клавиатуре. Пожалуй, это все, чем я хотел поделиться с вами в данной статье. Буду рад любой форме обратной связи. Благодарю за внимание и хорошего дня!  JavaScript Developer