useSWRInfinite
👉SWR 공식문서👈
SWR
은 페이지 매김 및 무한 로딩과 같은 일반적인 UI 패턴을 지원하기 위해 전용 API
useSWRInfinite
를 제공한다.
기존의 데이터를 가져올때 useSWR을 이용하여 데이터를 가져왔다. 이번 시간은 무한스크롤을 처리하기 위해 공부한다.
const fetcher = async (url: string) => {
return await axios.get(url).then(res => res.data)
}
const address = "http://localhost:4000/api/subs/sub/topSubs";
const {data: topSubs} = useSWR<Sub[]>(👉(address)👈, 👉fetcher👈);
기존에는 key
와 fetcher
를 넣어서 경로를 넣어줬지만
이번 useSWRInfinite
을 사용할 때는 그 자리에 getkey
라는 함수를 만들어 넣어준다.
계속 내리다가 더 이상 내릴(가져올) 포스트가 없다면 null
값을 return
함.
예제
const getKey = (pageIndex: number, previousPageData: Post[]) => {
if (previousPageData && !previousPageData.length) return null
return `/posts?page=${pageIndex}`
이렇게 getKey라는 함수를 만들고 const {data: topSubs} = useSWR<Sub[]>(👉getKey👈);
이 자리에 들어오게 된다.
예제 (반환값)
const {
1️⃣data,
2️⃣error,
3️⃣size: page,
4️⃣setSize: setPage,
5️⃣isValidating,
6️⃣mutate
} = useSWRInfinite<Post[]>(getKey);
👆반환 값 설명
1️⃣ data
: 각 페이지의 가져오기 응답 값의 배열
2️⃣ error
: useSWR의 error와 동일
3️⃣ size
: 가져올 페이지 및 반환될 페이지의 수
4️⃣ setSize
: 가져와야 하는 페이지의 수를 설정
5️⃣ isValidating
: useSWR의 isValidating과 동일
6️⃣ mutate
: useSWR의 바인딩 된 뮤테이트 함수와 동일하지만 데이터 배열을 다룬다
스크롤을 내리면 새로운 데이터를 무한스크롤로 가져오게 하려고 한다.
브라우저 뷰포트가 엘리먼트가 교차가 될 때 데이터를 가져오게 하는 방식이다. (뷰포트에 교차가 되는걸 지켜보면서 데이터를 불러온다)
예제
👉스크롤을 내려서 observedPost에 닿으면
👉다음 페이지 포스트들을 가져오기 위한 포스트 id state
const [ observedPost(관찰이 되고 있는 포스트), setObservedPost ] = useState();
👉Infinite Scroll 기능 구현
useEffect(() => {
👉포스트가 없다면 return
if(!posts || posts.length === 0) return;
👉posts 배열안에 마지막 post에 id를 가져온다.
const id = posts[posts.length - 1].identifier;
👉posts 배열에 post가 추가돼서 마지막 post가 바뀌었다면
👉바뀐 posts중 마지막 post를 observerdPost로
if(id !== observedPost) {
setObserverPost(id);
observerElement(document.getElementById(id);
}
}, [posts]);
const observeElement = (element: HTMLElement) => {
if(!element) return;
👉브라우저 뷰포트와 설정한 요소(element)의 교차점을 관찰
const observer = new IntersectionObserver(
(entries) => {
👉isIntersecting: 관찰 대상의 교차 상태(Boolean)
if(entries[0].isIntersecting === true) {
console.log("Reached bottom of post");
setPage(page + 1);
observer.unobserve(element);
}
},
👉옵저버가 실행되기 위해 타겟의 가시성이 얼마나 필요한지 백분율로 표시
{threshold: 1} //요소가 뷰포트에 1/2만 나와도 0.5의 값이 나온다 완전 뷰포트에 보여야하므로 1로 함
);
👉대상 요소의 관찰을 시작
observer.observe(element);
};
observer
Inersection observer
는 기본적으로 브라우져 뷰포트(Viewport)
와 설정한 요소(Element)
의 교차점을 관찰하며, 요소가 뷰포트에 포함되는지 포함되지 않는지, 더 쉽게는 사용자 화면에 지금 보이는 요소인지 아닌지를 구별하는 기능을 제공한다.
이 기능은 비동기적으로 실행되기 때문에, scroll 같은 이벤트 기반의 요소 관찰에서 문제없이 사용할 수 있다.