[TIL 41] React | Intersection Observer API를 활용한 무한스크롤

sunny·2021년 5월 9일
1
post-thumbnail

클론프로젝트를 하면서 꼭 한번 해보고 싶었던 무한 스크롤 기능과 로딩바 기능을 구현해보았다!


기존 scroll event의 문제점

스크롤을 끊임없이 감지하고 동기적으로 실행되기 때문에 메인 스레드에 영향을 준다.

실제로 스크롤 이벤트로 무한스크롤기능을 구현할때의 상황.
scroll이 맨 밑에 있을때 감지해주는 함수를 달아놨는데 스크롤이 계속 맨 밑에 머물러있을때 끊임없이 함수가 호출되고 있다.


Intersection Observer API

간단히 말하자면 타겟이 화면에 노출되었는 지의 여부를 관찰할 수 있는 API
교차되었을때 실행할 callback 함수와 option을 인자로 받는다.

const observer = new IntersectionObserver(callback, options);

callback

타겟 엘리먼트가 교차되었을 때 실행할 함수

options

observer 콜백이 호출되는 상황을 조작할 수 있다.

  • root
    • 교차 영역의 기준이 될 root 엘리먼트.
    • 기본값은 브라우저의 viewport
  • rootMargin
    • root엘리먼트의 margin값
  • threshold
    • 타겟에 대한 교차 영역 비율
    • 0의 경우 : 타겟 엘리먼트가 교차영역에 진입했을 시점에 observer를 실행
    • 1의 경우 : 타켓 엘리먼트 전체가 교차영역에 들어왔을 때 observer를 실행

method

  • IntersectionObserver.observe(target)
    • 타겟 엘리먼트에 대한 IntersectionObserver를 등록 (관찰 시작)
  • IntersectionObserver.unobserve(target)
    • 타겟 엘리먼트에 대한 관찰 중지
  • IntersectionObserver.disconnect()
    • 모든 타겟 엘리먼트에 대한 관찰 중지

React hook에 적용해보기

우선 target, 로딩중인지 아닌지를 판별해줄 isLoading, 현재 아이템 갯수를 나타내는 itemCount를 state로 지정해준다.

target에 변화가 있을때마다 실행해줄 useEffect에 observer 객체를 선언한다.

callback함수의 인자로 entry와 observer를 받는다. 타겟의 교차 상태를 boolean값으로 반환하는 entry.isIntersecting가 true일때 list를 fetch하는 함수를 호출하고 itemCount에 1을 더해 setState해준다. (난 한페이지당 1개의 리스트만 호출하고 스크롤이 끝에 다다랐을때 하나씩 더 보여주는 무한스크롤을 구현예정이다.)

리스트를 fetch해오는 함수.
우선 isLoading을 true로 setState해주고, fetch를 통해 백엔드로부터 데이터를 받아온다.
setTimeout을 통해 약간의 시간차를 줘 로딩바가 더 잘보일 수 있도록 했다.
list의 갯수가 현재 itemCount와 같으면 loading이 끝난것이기 때문에 다시 false로 바꿔주었고, list를 itemCount의 수만큼 slice해 setState해주었다.

마지막으로 컴포넌트가 언마운트될때 isLoading을 false로 setState해준다.

로딩바부분.
isLoading이 true일때만 로딩바가 보여야하므로 조건부렌더링을 걸어주었고 setTarget을 forwardRef로 지정해주었다.
처음엔 그냥 ref로 지정해주었는데 에러가 나길래 리액트 공식문서를 보다가 React 컴포넌트에 ref prop을 넘겨서 그 내부에 있는 HTML 엘리먼트에 접근을 하게 해주는 forwardRef 함수를 사용하라는 답변을 보고 forwardRef를 사용했다.

profile
blog 👉🏻 https://kimnamsun.github.io/

0개의 댓글