React에서의 무한스크롤 (IntersectionObserver)
이번 프로젝트에서는 React에서의 여러 무한스크롤 구현 방식 중,
IntersectionObserver
방식을 선택했다.
IntersectionObserver
는 교차 관찰자로, 기본 web API다. 관찰자(스크롤박스)를 설정하고, 그 스크롤 내에서 특정 관찰대상(target)이 화면에 보여지면 이를 캐치할 수 있도록 해준다.
🥷🏻 기본 사용 방법
new IntersectionObserver(callback, options)
를 선언하여 **관찰자(스크롤박스)**를 지정해준다. 그리고,useRef
를 통해 “_어떤 엘리먼트가 스크롤박스에서 보여지면 스크롤이 바닥에 닿았다고 인식되도록 할 것인가?_”의 기준이 될 관찰대상을 지정해준다.
관찰자 및 옵션 지정
1
2
3
4
5
6
7
8
9
10
11
12
13useEffect(() => {
// 옵션 설정
const options = {
root: null,
rootMargin: '0px',
threshold: 1,
};
// 관찰자 선언
const observer = new IntersectionObserver(fetcher, options);
// 만약 관찰대상 ref.current가 null이 아니면 ? -> 관찰 시작!
if (targetRef.current) observer.observe(targetRef.current);
return () => observer.disconnect();
}, [fetcher]);option 설정
- root: 관찰자를 설정해주는 필드다. default는 null(Viewport)다. (null일 때는, 뷰포트에 관찰대상이 보이면 알려줌)
- rootMargin: 관찰대상의 감지 영역에 margin값까지 포함시키고싶을 때 사용하면 된다. 문자열이 들어가야 한다.
- threshold: 관찰대상이 화면에 얼마나 보여질 때 콜백 함수를 호출할 지 결정한다. 범위는 0~1이다. (만약 1을 지정하면 관찰대상이 전부 보여졌을 때만 이를 인식한다)
관찰 대상 지정
useRef
를 통해 빈<div>
태그를 관찰대상으로 지정했다. 해당<div>
가 화면에 보여지면 스크롤이 바닥에 닿았다고 인식하도록 한 것이다.콜백함수 작성
이제 위의 option 조건이 만족되었을 때 발동될 콜백함수를 지정해주면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const fetcher = useCallback(
async (entry) => {
// 이 조건문은 아래에서 설명하도록 하겠다.
if (list.length < 1) return;
const target = entry[0];
if (target.isIntersecting) {
setRange((prev) => prev + 15);
const products = await axios.get(`api/productList`, {
params: { length: range, text: inputValue },
});
setResults(products.data.requests);
}
},
[inputValue, list]
);entry는 뭘까?
⇒ 관찰중인 대상들을 모두 담은 배열이다. 이번 프로젝트에서는 관찰대상이 targetRef 하나이므로,
entry[0]
만을 사용했다.
콜백함수에서 조건문을 사용한 이유
위의 코드에서 조건문을 통해
list.length
가 1보다 작을 때 콜백함수가return
종료되도록 했다. 뭐가 문제였을까?
검색결과가 없을 때 targetRef
가 화면에 보여진다..!
위의 사진에서 보이는 바와 같이, 검색 결과가 없을 때 targetRef가 위로 끌어올려지기 때문에 콜백함수가 실행된다. 따라서 검색결과가 없을 때, 즉 list.length < 1
일 때는 콜백함수가 실행되지 않도록 예외처리를 해준 것이다. 이로써 불필요한 API호출을 지양할 수 있었다.
React에서의 무한스크롤 (IntersectionObserver)