반응형
무한 스크롤 컴포넌트
import React, { useState, useEffect, useRef, FC } from "react";
interface Props {
fetchData: () => Promise<void>;
children: React.ReactNode;
}
const InfiniteScroll: FC<Props> = ({ fetchData, children }) => {
const [isLoading, setIsLoading] = useState(true);
const loader = useRef<HTMLDivElement>(null);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting) {
setIsLoading(true);
fetchData().then((newItems) => {
setIsLoading(false);
});
}
},
{ threshold: 1 }
);
if (loader.current) {
observer.observe(loader.current);
}
return () => {
observer.disconnect();
};
}, [loader, setIsLoading, fetchData]);
return (
<div>
{children}
<div ref={loader}>
{isLoading && "로딩..."}
</div>
</div>
);
};
export default InfiniteScroll;
사용법
export const List: React.FC = () => {
const [page, setPage] = useState(1);
const [list,setList] = React.useState([])
const fetchData = async () => {
const response = await axios.get(`https://api.example.com/data?page=${page}&limit=10`);
setList(prevData => [...prevData, ...response.data]);
};
return (
<InfiniteScroll fetchData={fetchData}>
<ul>
{list.map((item,i) => (
<li key={i}>item</li>
))}
</ul>
</InfiniteScroll>
);
};
해설
- InfiniteScroll 컴포넌트를 만들어서 재사용 가능하게 합니다.
- 재사용성을 높이기 위해서 로딩 상태와 UI를 InfiniteScroll내부에 구현합니다.
- 데이터를 저장할 data 상태와 페이지 번호를 저장할 page 상태를 생성합니다.
- 페이지 번호가 변경될 때마다 API를 호출하여 데이터를 가져옵니다. 가져온 데이터는 이전 데이터와 합쳐집니다.
- Intersection Observer를 설정하여 로딩 요소가 뷰포트와 교차할 때마다 페이지 번호를 증가시킵니다.
- 로딩 요소에 ref를 설정하여 Intersection Observer가 관찰할 수 있도록 합니다.
반응형
'개발관련 > 리액트' 카테고리의 다른 글
react에서 Windowing을 구현해보자 (0) | 2023.08.10 |
---|---|
[번역] 리액트 기술을 한 단계 업그레이드하세요: 2023년에 마스터할 고급 패턴 5가지 (0) | 2023.08.07 |
CRA test 할때 axios import outside 에러 관련 (0) | 2023.05.01 |
React 프로젝트에서 GZIP 압축 사용하기 (0) | 2023.05.01 |
React-hook-form과 Material UI MUI Select Component 같이 사용 하는 방법 (0) | 2022.11.03 |