Antd 테이블에서 무한 스크롤 구현하기

React 프로젝트에서 Antd 테이블을 사용하여 무한 스크롤(상단 또는 하단 로딩) 기능을 구현하는 방법에 대해 설명합니다.
테이블의 최대 높이를 지정하고, 스크롤 이벤트를 통해 데이터를 추가로 불러옵니다:
scroll={{ y: 500 }}
API 호출 시 페이지 번호를 확인하여 첫 페이지일 경우 새로운 데이터로 덮어쓰고, 그 외에는 기존 배열에 데이터를 추가합니다.
Antd 테이블의 body 영역에 스크롤 이벤트를 연결합니다:
document.querySelector('.ant-table-body').addEventListener('scroll', handleScroll);
스크롤 이벤트 핸들러에서는 마지막 페이지 여부를 판단하며, 비동기 API 호출 중복을 방지하기 위해 loading 상태를 사용합니다.
아래는 HTML 코드입니다:
<Table
  scroll={{ y: 500 }}
  columns={columns}
  dataSource={dataState.items}
  pagination={false}
  rowKey="uniqueId"
/>
다음은 TypeScript 코드입니다:
let scrollTop = 0;
let totalPages = 0;
let currentPage = 1;
let isFetching = false;

useEffect(() => {
  fetchData();
  const tableBody = document.querySelector('.ant-table-body');
  if (tableBody) {
    tableBody.addEventListener('scroll', handleScroll);
  }
  return () => {
    if (tableBody) {
      tableBody.removeEventListener('scroll', handleScroll);
    }
  };
}, []);

const handleScroll = (e) => {
  if (isFetching) return;

  const { scrollTop, clientHeight, scrollHeight } = e.target;
  if (scrollTop + clientHeight >= scrollHeight - 20) {
    if (currentPage < totalPages) {
      isFetching = true;
      currentPage++;
      fetchData();
    }
  }
  scrollTop = scrollTop;
};

const fetchData = async () => {
  const params = { page: currentPage, limit: 20 };
  const response = await apiService.fetchList(params);
  if (response.success) {
    totalPages = response.totalPages || 0;
    const newData = currentPage === 1 ? response.items : [...dataState.items, ...response.items];
    setDataState({ items: newData });
    isFetching = false;
  }
};
handleScroll 이벤트 핸들러에서 필요한 변수들은 useState나 상태 관리 라이브러리를 사용하지 않고 전역 변수처럼 선언해야 합니다. 이는 이벤트 핸들러가 리액트 컴포넌트의 상태 변경을 실시간으로 감지하지 못하기 때문입니다.
또한, Antd 테이블과 함께 react-window(가상 리스트)를 활용하면 더 효율적인 성능을 얻을 수 있습니다. 하지만 위와 같은 기본적인 접근법도 대부분의 상황에서 충분히 효과적입니다.

태그: antd React TypeScript

7월 31일 20:40에 게시됨