React Academy · Урок

Бесконечная прокрутка и разбиение на страницы с useInfiniteQuery

Получайте данные постранично и плавно загружайте следующие страницы с помощью useInfiniteQuery.

Урок 4 из 413 шагов

«Бесконечная прокрутка и разбиение на страницы с useInfiniteQuery» — бесплатный урок React Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.

Добро пожаловать

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

Что такое useInfiniteQuery?

useInfiniteQuery получает данные по «страницам». Каждая страница загружается отдельно и добавляется в кэшированный список. Он предоставляет функции fetchNextPage, hasNextPage и isFetchingNextPage.

Базовая настройка

Определите initialPageParam и getNextPageParam. Функция queryFn получает текущий pageParam и должна вернуть страницу результатов.
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
  queryKey: ['posts'],
  queryFn: ({ pageParam }) =>
    fetch('/api/posts?cursor=' + pageParam).then(r => r.json()),
  initialPageParam: 0,
  getNextPageParam: (lastPage) => lastPage.nextCursor ?? undefined,
});

getNextPageParam

getNextPageParam получает последнюю загруженную страницу и все страницы. Верните следующий курсор или номер страницы либо undefined/null, чтобы сообщить, что страниц больше нет (это устанавливает hasNextPage в false).
getNextPageParam: (lastPage, allPages) => {
  return lastPage.hasMore ? lastPage.nextCursor : undefined;
}

Отображение всех страниц

data.pages — это массив результатов страниц. Объедините их, чтобы отображать все элементы в виде единого непрерывного списка.
const allPosts = data.pages.flatMap(page => page.items);

return (
  <ul>
    {allPosts.map(post => <li key={post.id}>{post.title}</li>)}
  </ul>
);

Кнопка «Загрузить ещё»

Добавьте кнопку «Загрузить ещё», которая вызывает fetchNextPage. Отключайте её, когда страниц больше нет или выполняется загрузка.
<button
  onClick={() => fetchNextPage()}
  disabled={!hasNextPage || isFetchingNextPage}
>
  {isFetchingNextPage ? 'Loading...' : hasNextPage ? 'Load More' : 'No more posts'}
</button>

Бесконечная прокрутка с IntersectionObserver

Подключите IntersectionObserver к элементу div-маркеру в нижней части списка. Когда он попадает в область просмотра, автоматически вызывайте fetchNextPage.
const observerRef = useRef();
useEffect(() => {
  const observer = new IntersectionObserver(entries => {
    if (entries[0].isIntersecting && hasNextPage) fetchNextPage();
  });
  if (observerRef.current) observer.observe(observerRef.current);
  return () => observer.disconnect();
}, [hasNextPage, fetchNextPage]);

<div ref={observerRef} />  {/* sentinel at bottom */}

Двунаправленная бесконечная прокрутка

В приложениях для чатов поддерживайте прокрутку в обоих направлениях: используйте fetchNextPage для загрузки старых сообщений, а getPreviousPageParam и fetchPreviousPage — для новых.

Постраничная и курсорная пагинация

На основе смещения или страниц: initialPageParam=1, а getNextPageParam возвращает lastPage.page + 1. На основе курсора: используйте ID последнего элемента в качестве курсора. Курсорная пагинация стабильнее для изменяющихся данных.
// Offset-based
getNextPageParam: (lastPage) => lastPage.page + 1

Повторная загрузка бесконечных запросов

Вызов invalidateQueries для бесконечного запроса повторно загружает только первую страницу. Чтобы повторно загрузить все страницы, например после добавления новой публикации, используйте queryClient.resetQueries или refetchType: 'all'.

Быстрая проверка

Что должна вернуть getNextPageParam, чтобы сообщить, что страниц для загрузки больше нет?

Итоги

useInfiniteQuery накапливает страницы в data.pages. Используйте flatMap, чтобы объединить их для отображения. Чтобы остановить загрузку, возвращайте из getNextPageParam значение undefined. Запускайте fetchNextPage по нажатию кнопки или через IntersectionObserver для реализации бесконечной прокрутки.

Курс завершён

Поздравляем! Вы завершили курс **React Query: Управление состоянием сервера**. Теперь Вы умеете загружать данные, кэшировать их, изменять, разбивать на страницы и реализовывать бесконечную прокрутку с помощью TanStack Query.
Можно начать бесплатно

Изучай React с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
88
Уроки
324

Часто задаваемые вопросы

Урок «Бесконечная прокрутка и разбиение на страницы с useInfiniteQuery» бесплатный?

Да — полный текст урока «Бесконечная прокрутка и разбиение на страницы с useInfiniteQuery» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.

Чему я научусь в уроке «Бесконечная прокрутка и разбиение на страницы с useInfiniteQuery»?

Получайте данные постранично и плавно загружайте следующие страницы с помощью useInfiniteQuery. Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Academy?

Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Бесконечная прокрутка и разбиение на страницы с useInfiniteQuery»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Academy?

Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Настройка React Query и QueryClient
  2. Кэширование, время устаревания и фоновые запросы
  3. Мутации с useMutation
  4. Бесконечная прокрутка и разбиение на страницы с useInfiniteQuery
← Назад к React Academy