1. 문제 발생❓
제 프로젝트에서는 네비게이션바(GNB)의 버튼들이 두 가지 다른 기능을 수행해야 했습니다:
- 특정 섹션으로 자동 스크롤 되는 버튼 ( "/ " => 해당 섹션으로 이동 )
- 새로운 페이지로 이동하는 버튼 ( "/resource" )
이러한 두 기능을 사용하는 버튼이 각각 있었는데, 문제는 페이지 이동 후에도 원래의 페이지에서 자동 스크롤 기능을 유지해야 한다는 점이었습니다. 즉, 다른 페이지에서 특정 섹션으로 이동하는 버튼을 클릭 했을 때, 메인 페이지로 이동한 다음 해당 섹션으로 자동 스크롤 되어야 했습니다.
2. 해결 과정 📋
< 통합 네비게이션 핸들러 구현 >
이 문제를 해결하기 위해 useNavigationHandler 커스텀 훅을 개발했습니다. 이 훅은 버튼 클릭 시 동작을 결정하고, 필요에 따라 페이지 이동과 스크롤 기능을 순차적으로 처리합니다.
< 핵심 로직 >
type NavigationHandlerParams = {
ref?: string;
href?: string;
shouldOpenInNewTab?: boolean;
};
export const useNavigationHandler = () => {
const router = useRouter();
const scrollToSection = useScrollToSection();
return function handleNavigation(
e: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
item: NavigationHandlerParams
) {
if (item.ref) {
e.preventDefault();
if (window.location.pathname !== "/" && window.location.pathname !== "") {
router.push("/");
setTimeout(() => {
if (item.ref) {
scrollToSection(e, item.ref);
}
}, 300);
return;
}
scrollToSection(e, item.ref);
return;
}
};
};
< 동작 방식 >
1. 경로 확인: 현재 사용자가 메인페이지("/")에 있는지 확인합니다.
if (window.location.pathname !== "/" && window.location.pathname !== "")
2. 페이지 이동 + 스크롤: 만약 메인 페이지가 아니라면:
- 먼저 메인 페이지("/")로 이동합니다.
- 페이지 이동 후 300ms 지연을 두고 해당 섹션으로 스크롤 합니다.
- 이 지연은 페이지가 완전히 로드되어 DOM 요소가 렌더링될 시간을 확보합니다.
if (window.location.pathname !== "/" && window.location.pathname !== "") {
router.push("/");
setTimeout(() => {
if (item.ref) {
scrollToSection(e, item.ref);
}
}, 300);
return;
}
3. 단순 스크롤: 이미 메인 페이지에 있다면, 바로 해당 섹션으로 스크롤합니다.
scrollToSection(e, item.ref);
return;
< 구현 세부 사항 >
1. useNavigationHandler 훅은 다음 파라미터를 받습니다.
- ref: 스크롤할 섹션의 선택자
- href: 이동할 페이지 URL
- shouldOpenInNewTab: 새 탭에서 열지 여부
2. 네비게이션 바에서 모든 링크는 이 핸들러를 사용하지만, 각 링크의 속성에 따라 다르게 동작합니다.
href={href || ref}
onClick={(e) => handleNavigation(e, { ref, href, shouldOpenInNewTab })}
target={shouldOpenInNewTab ? "_blank" : undefined}
key={index}
className="text-base font-bold px-2.5 py-2 rounded-md hover:bg-accent hover:text-accent-foreground"
>
{label}
</a>
4. 결과 ❤🔥
< 해결된 문제점 >
1. 멀티 페이지 환경에서의 스크롤 기능: 다른 페이지에서도 특정 섹션으로 이동하는 기능이 가능해졌습니다.
2. UX 개선: 사용자가 원하는 섹션으로 자연스럽게 이동할 수 있게 되었습니다.
3. 코드 재사용성: 데스크톱과 태블릿 뷰에서 동일한 핸들러를 사용할 수 있게 되었습니다.
'인턴' 카테고리의 다른 글
useMemo와 useCallback (0) | 2025.03.25 |
---|---|
Jotai (0) | 2025.03.25 |
[ Troubleshooting🛠️ ] Map 객체와 배열 간 타입 불일치 (0) | 2025.03.25 |
[ Troubleshooting🛠️ ] HTML <picture>과 <source> 태그 활용하기 (0) | 2025.03.25 |
Vercel CLI을 이용한 환경변수 세팅 (0) | 2025.03.25 |