1. 타겟 element 가 viewport 안에 보이는지 판단하는 hook
- input
- element: 관찰하고자 하는 타겟 element React.ref
- rootMargin : 관찰 타겟 주위의 여백, new IntersectionObserver() 생성자에, option 으로 들어가는 값.
- 예시. "10px 20px 30px 40px" (위, 오른쪽, 아래, 왼쪽). 값은 백분율이 될 수 있습니다. 기본값은 0.
- 타겟 주변의 여백도 포함해서, 그 여백까지 타겟으로 보고, viewport 에서 사라졌는지 판단함.
- IntersectionObserver.option.rootMargin 더보기
- output
- isVisible : 해당 타겟이 현재 viewport 안에 보이는지 여부 boolean.
- observer : 생성한 IntersectionObserver 인스턴스
- unmount 시키면서, 생성한 observer 인스턴스 관찰 unobserve 시키기 위함
useVisibilityObserver.ts
- 코드
import { useState, useEffect, RefObject } from "react";
interface VisibilityObserverResult {
isVisible: boolean;
observer: IntersectionObserver | null;
}
const useVisibilityObserver = (
element: RefObject<HTMLElement | null>,
rootMargin: string,
): VisibilityObserverResult => {
const [isVisible, setState] = useState(false);
const [observer, setObserver] = useState<IntersectionObserver | null>(null);
useEffect(() => {
if (element.current) {
const intersectionObserver = new IntersectionObserver(
([entry]) => {
setState(entry.isIntersecting);
},
{ rootMargin },
);
setObserver(intersectionObserver);
intersectionObserver.observe(element.current);
// Cleanup: Disconnect the observer when the component unmounts
return () => {
intersectionObserver.disconnect();
};
}
}, [element, rootMargin]); // Make sure to include 'element' and 'rootMargin' in the dependency array
return { isVisible, observer };
};
export default useVisibilityObserver;
MyComponent.tsx
- 사용하는 컴포넌트 코드
const targetElRef = useRef<HTMLDivElement | null>(null);
const { isVisible: inViewport, observer } = useVisibilityObserver(targetElRef, "100px");
useEffect(() => {
return () => {
observer && targetElRef.current && observer.unobserve(targetElRef.current);
};
}, [observer]);
...
return (
...
<div ref={targetElRef}>TEST</div>
...
<div style={{ margin: "10px", display: inViewport ? "block" : "none" }}>BOTTOM</div>
...
)
- 화면
- TEST 박스가 화면안에 보일때는 BOTTOM 박스도 노출됨
- TEST 박스가 화면 밖으로 사라지면 BOTTOM 글씨도 사라짐