프로젝트 무한스크롤 구현에 사용하려고 팀원분이 만들어두었던 훅을 보게되었는데
IntersectionObserver
API를 처음 알게되어 내용을 찾아보았다
브라우저의 Viewport
와 target
으로 설정한 엘리먼트의 교차영역을 관찰하며 요소가 뷰포트와의 겹치는 영역이 있는지 구별하는 기능을 제공해주는 API다
Viewport
는 화면 크기를 이야기하며 웹 페이지가 브라우저 화면상에서 실제로 표시되는 영역이다
new IntersectionObserver
생성자 함수로 생성한 인스턴스로 관찰자를 초기화하고 인수로 콜백,옵션
을 가진다
let observer = new IntersectionObserver(callback, options); // 관찰자 초기화
observer.observe(element) // 관찰할 대상(요소) 등록
콜백함수는 관찰대상이 등록
되거나
가시성의 변화(Visibility, 보이는지 보이지 않는지)
가 생기면
관찰자는 콜백을 실행한다
관찰대상 엘리먼트와 루트 엘리먼트와 겹치는 영역이 생기면 옵저버는 콜백함수를 실행하게 된다.
콜백함수는 entries
,observer
를 인수로 받는다.
IntersectionObserver 인스턴스의 배열이다
IntersectionObserverEntry
: 인터페이스는 특정 전환 순간에 대상 요소와 해당 루트 컨테이너 간의 교차를 설명한다
let callback = (entries, observer) => {
entries.forEach(entry => {
// Each entry describes an intersection change for one observed
// target element:
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
};
interface IntersectionObserverEntry {
readonly boundingClientRect: DOMRectReadOnly;
readonly intersectionRatio: number;
readonly intersectionRect: DOMRectReadOnly;
readonly isIntersecting: boolean;
readonly rootBounds: DOMRectReadOnly | null;
readonly target: Element;
readonly time: DOMHighResTimeStamp;
}
hook에서 사용 된 isIntersecting
는 관찰 대상 엘리먼트가 루트와 영역이 겹치는지 여부를 나타낸다
콜백이 실행되는 해당 인스턴스를 참조한다
옵저버의 메소드는 3가지가 있다 (관찰자 메소드)
observe()
: 관찰 대상의 관찰을 시작한다
unobserve()
: 관찰 대상의 관찰을 중지한다
disconnect()
: intersectionObserver 인스턴스들의 모든 관찰을 중지한다
인터섹션옵저버 생성자함수를 선언 할 때 옵션값도 넘기게되는데
옵션값으로는 root, rootmargin, thresholds 를 갖는다
threshold
는 옵저버의 콜백함수가 실행되기 위해서 관찰대상의 엘리먼트와 루트 앨리먼트가 겹치는 영역이 얼마나 필요한지 백분율로 표시한다
ex) 0.5
로 설정을 하게 되면 관찰 대상 엘리먼트가 루트엘리먼트와 50% 겹칠 때 옵저버가 콜백함수를 실행한다
import { useEffect, useRef, useState } from 'react';
export default function useIntersectionObserver() {
const ref = useRef<HTMLDivElement>(null);
const [visible, setVisible] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(([entry]) => {
setVisible(entry.isIntersecting);
});
// 등록되거나 가시성의 변화가 생길 때 실행되는 콜백
if (ref.current) {
observer.observe(ref.current); // 관찰할 대상(요소) 등록
}
return () => {
observer.disconnect();
};
}, [ref]);
return { ref, visible };
}
같이 프로젝트를 진행해준 팀원 덕분에 새로운 내용들을 많이 공부하게되는거 같아서 항상 감사한마음이다 🙂
훅은 구현해두었지만 결론적으로는 라이브러리를 사용하는 형태로 훅을 사용하지 않게 되었다
훅을 통해서 구현되는 방식을 추가적으로 공부하게 되었고 유용한 라이브러리도 알아갈 수 있었다