InView
InView는 IntersectionObserver를 선언적으로 활용 할 수 있는 컴포넌트입니다.
- @modern-kit/react의 useIntersectionObserver 훅을 사용하여 구현되었습니다.
관찰 대상이 Viewport에 노출될 때(onIntersectStart) 혹은 나갈 때(onIntersectEnd) 특정 action 함수를 호출 할 수 있는 컴포넌트입니다.
다형성(polymorphism)
InView 컴포넌트는 다형성을 위해 as 속성을 지원합니다.
- 기본적으로 div태그로 자식 요소를 감싸서 렌더링하며,as속성을 통해 감싸는Wrapper요소의 태그를 변경해 렌더링할 수 있습니다. (ex. div -> article)
- 이때, 해당 Wrapper요소가IntersectionObserver의 관찰 대상이 됩니다.
합성(Composition), 렌더링 위임(Rendering Delegation)
InView 컴포넌트는 asChild 속성을 통해 합성(Composition), 렌더링 위임(Rendering Delegation) 패턴을 지원합니다.
- asChild속성이- true라면 Slot 을 통해 래퍼 요소 없이 자식 요소를 그대로 렌더링합니다.
- 이때, 해당 자식 요소가 IntersectionObserver의 관찰 대상이 됩니다.- Slot의 자식은 단일 요소만 허용됩니다.
- Slot은 자식으로 컴포넌트가 올 경우 forwardRef,props를 허용해야 합니다. 허용하지 않으면 정상적으로 동작하지 않습니다.
- asChild속성을 사용 할 경우 Slot 문서를 참고해주세요.
 
- Slot의 자식은 
Code
Interface
typescript
interface InViewProps extends UseIntersectionObserverProps {
  children: React.ReactNode;
  asChild?: boolean;
}
typescript
const InView: PolyForwardComponent<"div", InViewProps, React.ElementType>
Usage
Default
- 기본적으로 div로 감싸지며, 해당div가IntersectionObserver의 관찰 대상이 됩니다.
- 해당 div가 viewport에 노출되거나 숨겨질 때onIntersectStart/onIntersectEnd콜백 함수를 호출합니다.
typescript
import { InView } from '@modern-kit/react';
const Example = () => {
  const handleIntersectStart = () => {/* action */}
  const handleIntersectEnd = () => {/* action */}
  return (
    <InView onIntersectStart={handleIntersectStart} onIntersectEnd={handleIntersectEnd}>
      <div>Box1</div>
    </InView>
  );
}; 
as
- as속성을 통해 특정 요소로 렌더링할 수 있으며, 해당 요소가- IntersectionObserver의 관찰 대상이 됩니다.
- 해당 요소가 viewport에 노출되거나 숨겨질 때 onIntersectStart/onIntersectEnd콜백 함수를 호출합니다.
typescript
import { InView } from '@modern-kit/react';
const Example = () => {
  const handleIntersectStart = () => {/* action */}
  const handleIntersectEnd = () => {/* action */}
  return (
    <InView
      as='ul' // div가 아닌 ul 요소로 감싸 렌더링
      onIntersectStart={handleIntersectStart}
      onIntersectEnd={handleIntersectEnd}
    >
      <li>List Item1</li>
      <li>List Item2</li> 
    </InView>
  );
}; 
asChild
- asChild속성이- true라면 Slot 을 통해 래퍼 요소 없이 자식 요소를 그대로 렌더링하고, 해당 자식 요소가- IntersectionObserver의 관찰 대상이 됩니다.
- 자식 요소가 viewport에 노출되거나 숨겨질 때 onIntersectStart/onIntersectEnd콜백 함수를 호출합니다.
typescript
import { InView } from '@modern-kit/react';
const Example = () => {
  const handleIntersectStart = () => {/* action */}
  const handleIntersectEnd = () => {/* action */}
  return (
    <InView asChild onIntersectStart={handleIntersectStart} onIntersectEnd={handleIntersectEnd}>
      <div>Box1</div>
    </InView>
  );
}; 
Example
스크롤 해주세요.
브라우저 개발자 도구의 콘솔을 확인해주세요.
Box1
calledOnce: true
as: div
Box3
calledOnce: false
asChild: true