Navbar에서 특정 메뉴를 클릭했을 때 현재 위치에 따라서 해당 메뉴에 데코레이션 효과가 들어가있는 것을 많이 보았을 것이다. (아래 사진과 같다.)
이러한 효과를 구현하고 싶은데 이 효과의 이름이 무엇인지를 몰라서 헤매다가 'navbar active'를 검색했더니 이것이 바로 tintcolor
라는 것을 알게 되었다.
나는 Next.js의 신버전인 13버전을 사용해서 구현했는데, 어떻게 구현했는지 설명해보겠다.
컴포넌트는 두 개를 사용했다.
💡Next.js 13의
usePathname
훅을 이용한다. (공식 문서 설명)MenuItemWrapper 컴포넌트에 props로 전달된 path와
usePathname
으로 얻어낸 pathname을 비교해서 같으면 active 상태로 판단하고 특별한 스타일을 입혀주는 것이다.
참고) 원래는 Next.js 12 버전에 있던대로 useRouter
훅을 이용해서 router.pathname
으로 접근하려고 했는데, Next.js 13 버전으로 업그레이드되면서 router object에 pathname이라는 속성이 없어지고, 따로 usePathname
이라는 훅으로 빠졌다.
쉽게 설명하기 위해서 아래의 코드에서 필요한 스타일만 클래스명으로 썼다.
MenuItemWrapper
import { usePathname } from 'next/navigation';
function MenuItemWrapper({
children,
onClick,
href,
}: {
children: React.ReactNode;
onClick?: React.MouseEventHandler<HTMLDivElement>;
href?: string;
}) {
const pathname = usePathname();
const isActive = pathname === href;
return (
<div
className={`${ isActive ? "border-l-4 border-white bg-hover-crimson" : ""}`}
onClick={onClick}
>
{children}
</div>
);
}
Sidebar
function Sidebar() {
return(
<nav>
<Link href="/main/mypage">
<MenuItemWrapper href="/main/mypage">
<RxPerson size={30} />
<span>내 정보</span>
</MenuItemWrapper>
</Link>
<Link href="/main">
<MenuItemWrapper href="/main">
<AiOutlineGlobal size={30} />
<span>활동 스트림</span>
</MenuItemWrapper>
</Link>
<Link href="/main/course">
<MenuItemWrapper href="/main/course">
<ImBook size={30} />
<span>코스</span>
</MenuItemWrapper>
</Link>
</nav>
);
}
이렇게 usePathname
훅을 사용하면 Next.js 13에서 Active Colortint를 구현할 수 있다.