[React + NEXT.JS Study] useSWRInfinite 란? + Intersection observer

JooSehyun·2023년 4월 17일
0

[Study]

목록 보기
14/31
post-thumbnail

React + NEXT.JS Study

useSWRInfinite 란?

useSWRInfinite

👉SWR 공식문서👈

SWR은 페이지 매김 및 무한 로딩과 같은 일반적인 UI 패턴을 지원하기 위해 전용 API useSWRInfinite를 제공한다.

기존의 데이터를 가져올때 useSWR을 이용하여 데이터를 가져왔다. 이번 시간은 무한스크롤을 처리하기 위해 공부한다.


기존 SWR을 사용할 때
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👈);

기존에는 keyfetcher를 넣어서 경로를 넣어줬지만
이번 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의 바인딩 된 뮤테이트 함수와 동일하지만 데이터 배열을 다룬다


Intersection observer API

스크롤을 내리면 새로운 데이터를 무한스크롤로 가져오게 하려고 한다.

브라우저 뷰포트가 엘리먼트가 교차가 될 때 데이터를 가져오게 하는 방식이다. (뷰포트에 교차가 되는걸 지켜보면서 데이터를 불러온다)

예제

👉스크롤을 내려서 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 같은 이벤트 기반의 요소 관찰에서 문제없이 사용할 수 있다.


0개의 댓글