useIntersectionObserver
ref를 할당한 타겟 엘리먼트가 Viewport에 노출될 때(onIntersectStart) 혹은 나갈 때(onIntersectEnd) 특정 action 함수를 호출 할 수 있는 컴포넌트입니다.
calledOnce옵션을 true로 설정하면 onIntersectStart와 onIntersectEnd를 각각 한번씩 호출 할 수 있습니다.
enabled옵션을 통해 onIntersect* 콜백 함수들의 호출을 제어 할 수 있습니다. false라면 타겟 엘리먼트가 Viewport에 노출하더라도 실행되지 않습니다.
Intersection Observer Option을 설정할 수 있습니다.(하단 Note 참고)
Code
Interface
typescript
interface IntersectionObserverInit {
root?: Element | Document | null;
rootMargin?: string;
threshold?: number | number[];
}
interface UseIntersectionObserverProps extends IntersectionObserverInit {
onIntersectStart?: (entry: IntersectionObserverEntry) => void;
onIntersectEnd?: (entry: IntersectionObserverEntry) => void;
calledOnce?: boolean;
enabled?: boolean;
}
interface UseIntersectionObserverReturnType<T extends HTMLElement> {
ref: React.RefCallback<T>;
isIntersecting: boolean;
hasIntersected: boolean;
}
typescript
function useIntersectionObserver<T extends HTMLElement>({
onIntersectStart,
onIntersectEnd,
enabled, // default: true
calledOnce, // default: false
root, // default: null
threshold, // default: 0
rootMargin, // default: '0px 0px 0px 0px'
}: UseIntersectionObserverProps = {}): UseIntersectionObserverReturnType<T>;
Options
| Name | Type | Default | Description |
|---|---|---|---|
onIntersectStart | (entry: IntersectionObserverEntry) => void | - | 타겟이 뷰포트에 진입할 때 호출되는 콜백 |
onIntersectEnd | (entry: IntersectionObserverEntry) => void | - | 타겟이 뷰포트를 벗어날 때 호출되는 콜백 |
calledOnce | boolean | false | true이면 각 콜백을 한 번씩만 호출합니다 |
enabled | boolean | true | 옵저버 콜백 활성화 여부 |
root | Element | Document | null | null | 뷰포트로 사용할 요소 |
threshold | number | number[] | 0 | 콜백을 트리거할 가시성 비율 임계값 |
rootMargin | string | '0px 0px 0px 0px' | 루트 요소 주변의 여백 |
Returns
| Name | Type | Description |
|---|---|---|
ref | React.RefCallback<T> | 타겟 요소에 연결할 ref 콜백 |
isIntersecting | boolean | 타겟이 현재 뷰포트와 교차하는지 여부 |
hasIntersected | boolean | 타겟이 뷰포트와 한 번이라도 교차했는지 여부 |
Usage
typescript
import { useIntersectionObserver } from '@modern-kit/react';
const Example = () => {
const [value, setValue] = useState(0);
const [enabled, setEnabled] = useState(true);
const { ref: targetRef, isIntersecting, hasIntersected } = useIntersectionObserver({
onIntersectStart: (entry) => {
console.log("onIntersectStart: ", entry);
setValue(value + 1);
},
onIntersectEnd: (entry) => {
console.log("onIntersectEnd: ", entry);
setValue(value + 1);
},
enabled,
});
const boxStyle = {
height: "800px",
backgroundColor: "teal"
}
return (
<div>
<button onClick={() => setEnabled(!enabled)}>Enabled: {`${enabled}`}</button>
<p>isIntersecting: {`${isIntersecting}`}</p>
<p>hasIntersected: {`${hasIntersected}`}</p>
<div style={boxStyle} />
<div ref={targetRef} style={{ color: "white", fontSize: "24px", backgroundColor: "blue" }}>
<div>타겟 요소 <br/> value: {value}</div>
</div>
<div style={boxStyle} />
</div>
);
};
Example
isIntersecting: false
hasIntersected: false
타겟 요소
value: 0
value: 0