Coding Planet
[Next.js]스크롤 컨테이너에 대한 'ScrollToTop' 컴포넌트 구현하기 - 맨 위로 버튼 본문
반응형
일반적으로 ScrollToTop 컴포넌트는 window 객체의 스크롤을 감지하여 구현한다. 하지만 특정 div 내에서만 스크롤이 발생하는 경우 window.pageYOffset은 항상 0을 반환하여 스크롤 위치를 정확히 파악할 수 없다. 무한 스크롤 게시판의 경우 맨 위로 가기 버튼이 필수적이므로 이 기능을 스크롤 컨테이너에서만 적용되도록 구현했다. 다만 예시코드에서는 무한 스크롤 부분은 코드의 가독성을 위해 제거하고 ScrollToTop 기능만 나와있다.
| 접근 방법
1. 스크롤 가능한 컨테이너에 ref를 할당한다.
2. 이 ref를 'ScrollToTop' 컴포넌트에 전달한다.
3. 'ScrollToTop' 컴포넌트 내에서 해당 ref의 scrollTop 속성을 사용하여 스크롤 위치를 감지한다.
| useRef
- useRef는 참조를 저장하기 위해 사용된다. 주로 DOM 요소에 접근하거나, 렌더링 사이에서 값을 유지하기 위해 사용하는데 이 경우 스크롤값을 참조하고 저장한다.
- 값이 변경되어도 컴포넌트가 다시 렌더링되지 않는다
| useCallback
- 메모이제이션된 콜백 함수를 반환한다. 컴포넌트가 재렌더링될 때, 동일한 콜백 함수를 다시 생성하지 않도록 함으로써 성능을 최적화한다.
| 소스
Board
import React, { useState, useRef } from 'react';
import ScrollToTop from "@/app/components/util/ScrollToTop";
export default function Board() {
const scrollContainerRef = useRef(null);
return (
<>
<div
ref={scrollContainerRef}
className="w-full bg-white p-4 pb-20 box-border overflow-y-auto h-[calc(100vh-105px)] mt-[80px] focus:outline-none"
>
<ScrollToTop scrollContainerRef={scrollContainerRef} />
{/* 컨텐츠 */}
</div>
</>
);
}
ScrollToTop Component
import React, { useEffect, useState, useCallback } from 'react';
const ScrollToTop = ({ scrollContainerRef }) => {
const [isVisible, setIsVisible] = useState(false);
const handleScroll = useCallback(() => {
const scrollContainer = scrollContainerRef.current;
if (scrollContainer) {
console.log('Scroll position:', scrollContainer.scrollTop);
if (scrollContainer.scrollTop > 100) {
setIsVisible(true);
} else {
setIsVisible(false);
}
}
}, [scrollContainerRef]);
const scrollToTop = () => {
const scrollContainer = scrollContainerRef.current;
if (scrollContainer) {
scrollContainer.scrollTo({
top: 0,
behavior: 'smooth',
});
}
};
useEffect(() => {
const scrollContainer = scrollContainerRef.current;
if (scrollContainer) {
scrollContainer.addEventListener('scroll', handleScroll);
return () => {
scrollContainer.removeEventListener('scroll', handleScroll);
};
}
}, [handleScroll, scrollContainerRef]);
return (
<>
{isVisible && (
<div
onClick={scrollToTop}
className="fixed bottom-5 right-5 bg-blue-600 text-white p-3 rounded-full cursor-pointer shadow-lg"
style={{ zIndex: 9999 }}
>
위로
</div>
)}
</>
);
};
export default ScrollToTop;
반응형
'front' 카테고리의 다른 글
[React] PWA를 위한 webpack 설정 : create-app-react를 사용하지 않은 경우 (0) | 2024.07.11 |
---|---|
[React] redux-persist 설치 및 환경설정 (store.js 예시) (0) | 2024.07.10 |
[React] Redux-saga - 비동기 작업을 더 쉽게 관리할 수 있게 해주는 미들웨어 (0) | 2024.07.04 |
[React] React에서 이벤트 핸들러 전달: 익명 함수 vs 함수 참조 (0) | 2024.06.28 |
[React] 배열 디스트럭처링(array destructuring) - Hook (0) | 2024.06.27 |
Comments