Вот пример того, как вы можете реализовать бесконечную прокрутку с помощью хука React и GraphQL:

import { useState, useEffect } from 'react';
import { useQuery } from '@apollo/client';

const ITEMS_PER_PAGE = 10;

function useInfiniteScroll(query, variables, pageKey) {
  const [loading, setLoading] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const { data, fetchMore } = useQuery(query, { variables });

  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  function handleScroll() {
    if (loading || !hasMore) return;
    if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight) return;
    setLoading(true);
  }

  function fetchMoreData() {
    fetchMore({
      variables: {
        ...variables,
        [pageKey]: data[pageKey] + 1
      },
      updateQuery: (prev, { fetchMoreResult }) => {
        if (!fetchMoreResult) return prev;
        setLoading(false);
        setHasMore(fetchMoreResult[pageKey].length === ITEMS_PER_PAGE);
        return Object.assign({}, prev, {
          [pageKey]: [...prev[pageKey], ...fetchMoreResult[pageKey]]
        });
      }
    });
  }

  useEffect(() => {
    if (!loading) return;
    fetchMoreData();
  }, [loading]);

  return {
    data,
    loading,
    hasMore
  };
}

export default useInfiniteScroll;

Этот хук использует хук useQuery из библиотеки @apollo/client для выполнения запроса GraphQL и получения данных. Он также использует хук useState для отслеживания состояния загрузки и наличия дополнительных элементов для загрузки.

Хук устанавливает прослушиватель событий для события scroll, чтобы отслеживать положение прокрутки пользователя. Когда пользователь прокручивает страницу до конца, хук устанавливает состояние загрузки в true и запускает выборку дополнительных данных.

Хук использует функцию fetchMore из @apollo/client для выполнения нового запроса с обновленным номером страницы в качестве переменной. Затем он обновляет результат запроса новыми данными и соответствующим образом устанавливает состояния загрузки и hasMore.

Надеюсь, это поможет! Дайте знать, если у вас появятся вопросы.