WebPublisher/React

[next.js] useIntersectionObserver hook & next/dynamic 사용하기

amanda 2024. 8. 12. 17:40

next.js 환경에서 스크롤 이벤트 구현하기

 

요구사항은 스크롤이 특정 영역에 진입했을 때 canvas로 그린 animation이 구현되는 것이었다

 

 

스크롤을 감지하기 위해 JS의 intersection observer 기능을 사용했고

next.js 환경에서 사용하고자 useIntersectionObserver hook을 생성했다.

 

그리고 페이지 초기 렌더링 시에는 해당 canvas animation이 로드되지 않고

scroll event가 수행될 때 canvas 컴포넌트가 렌더링 되도록 하기 위해

next/dynamic을 import 했다.

 

 

 

src > hooks > useIntersectionObserver.ts

import { useEffect, useState, useRef } from 'react';

const useIntersectionObserver = (options: IntersectionObserverInit) => {
  const [isIntersecting, setIsIntersecting] = useState(false);
  const ref = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      setIsIntersecting(entry.isIntersecting);
    }, options);

    if (ref.current) {
      observer.observe(ref.current);
    }

    return () => {
      if (ref.current) {
        observer.unobserve(ref.current);
      }
    };
  }, [options]);

  return { ref, isIntersecting };
};

export default useIntersectionObserver;

 

 

 

hook을 사용하는 CanvasTestPage.tsx

next/dynamic과 useIntersectionObserver를 import

'use client';

import dynamic from 'next/dynamic';
import useIntersectionObserver from '@/hooks/useIntersectionObserver';

const DynamicCanvas = dynamic(() => import('@/components/index/CanvasAnimation'), { 
  ssr: false, 
});

function CanvasTestPage() {
	const { ref, isIntersecting } = useIntersectionObserver({
        root: null,
        rootMargin: '0px',
        threshold: 0.5,
    });

  return (
      <div className="sub_inner">
        <div ref={ref} className="canvas_wrap">
          {isIntersecting && <DynamicCanvas />}
        </div>
      </div>
  );
}

export default CanvasTestPage;

 

 

 

canvas animation을 구현하는 CanvasAnimation.tsx

'use client';
import React, { useRef, useEffect } from 'react';

const CanvasAnimation: React.FC = () => {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  
  useEffect(() => {
    const canvas = canvasRef.current;
    
    // canvas animation 구현 함수 삽입 위치
    
  }, []);
  
  return (
  	<div className="canvas_effect">
    	<canvas
        	className="canvas"
            ref={canvasRef}
        ></canvas>
    </div>
  )
}

export default CanvasAnimation;

 

 

 

 

 

*참고

https://velog.io/@hyesungoh/%EB%82%B4%EA%B0%80-Intersection-Observer-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95

 

내가 Intersection Observer 사용하는 방법

본 게시물은 제 개인 블로그에서도 확인하실 수 있습니다infinite scroll, lazy loading 등 특정 요소가 보이는지 감지하는 것은 다양한 이유로써 사용된다.이를 위해 단순 scroll을 감지하여 사용할 수도

velog.io

 

https://velog.io/@hwisaac/NextJS-dynamic-import-%EA%B5%AC%EB%AC%B8

 

NextJS: dynamic import

Next.js의 dynamic import는 import() 구문을 사용하여 코드 분할(Code Splitting)을 구현하는 방법입니다.Next.js에서는 dynamic import 구문을 사용하면 코드를 동적으로 로드할 수 있습니다. 다음은 Next.js에서 코

velog.io