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/@hwisaac/NextJS-dynamic-import-%EA%B5%AC%EB%AC%B8