대부분의 웹 사이트는 top navigation bar를 가지고 있는데, 이 navigation bar를 스타일링 할 때 사용자의 activation, pending 상태에 따라 별도 스타일을 적용해 현재 사용자가 어디에 있는 지, 어디로 이동하는 지 알려주곤 한다.
React Router에서 navigation 상태를 알기 위한 방법은 다음 두 가지가 있다.
<NavLink>
React Router의 <NavLink>
컴포넌트는 isActive, isPending 이라는 함수를 지원해주어 navigation 상태에 따른 스타일링을 편하게 할 수 있도록 해준다.
import { NavLink } from "react-router-dom";
<NavLink
to-"/messages"
className={({ isActive, isPending }) =>
isPending ? "pending" : isActive ? "active" : ""
}
>
Messages
</NavLink>;
active
class활성화 상태일 때 <NavLink>
는 active
class가 기본 적용 되어 있다. 따라서 active style을 변경하기 위해서는 다음과 같이 하면 된다.
<nav id="sidebar">
<NavLink to="/messages" />
</nav>
#sidebar a.active {
color: red;
}
NavLink의 className, style prop은 일반적인 className, style과 동일하게 동작하지만, 커스터마이징한 함수를 전달할 수도 있다.
<NavLink
to="/messages"
className={({ isActive, isPending }) =>
isPending ? "pending" : isActive ? "active" : ""
}
>
Messages
</NavLink>
<NavLink
to="/messages"
style={({ isActive, isPending }) => {
return {
fontWeight: isActive ? "bold" : "",
color: isPending ? "red" : "black",
};
}}
>
Messages
</NavLink>
<NavLink>
의 content를 커스텀하기 위해 render prop을 상속할 수도 있다.
<NavLink to="/tasks">
{({ isActive, isPending }) => (
<span className={isActive ? "active" : ""}>Tasks</span>
)}
</NavLink>
end prop은 active, pending state를 적용할 때 적용 범위의 end path를 지정해줄 수 있다.
예를 들어, <NavLink>
에 to="/" 속성만 지정해준다면 "/"가 포함된 하위 링크에서도 active 상태로 인식될 것이다. 하지만 end prop을 명시해 줄 경우 "/" 이후 하위 링크는 더이상 active 상태로 인지하지 않게 된다.
<NavLink to="/">Home</NavLink> // alway active state
<NavLink to="/" end>Home</NavLink> // only active at "/"
caseSensitive prop을 추가할 경우 URL 매칭 시 대소문자 등 엄격한 구분을 하게 된다.
<NavLink>
가 active state일 때, <a aria-current="page">
가 자동 적용되어 있다.
aria-current에 대한 학습은 이후에 진행할 예정, https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current
reloadDocument 속성을 사용하여 client side routing을 스킵하고 정상적으로 브라우저 트렌지션할 수 있다. (<a href>
와 같음)
reloadDocument도 나중에 따로 찾아봐야 할 것 같다
useMatch의 자세한 내용은 Dynamic Segments를 참고할 수 있다. useMatch를 이용해서 active/pending style 변경을 쉽게 할 수 있다.
function SomeComp() {
const match = useMatch("/messages");
return <li className={Boolean(match) ? "active" : ""} />;
}