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(가상 리스트)를 활용하면 더 효율적인 성능을 얻을 수 있습니다. 하지만 위와 같은 기본적인 접근법도 대부분의 상황에서 충분히 효과적입니다.