들어가며
하단 네비게이션바를 작업하면서 페이지를 전환과 현재 페이지 상태를 불러오는 기능이 필요했습니다.
이에 대한 방안으로
- window.location.href를 파싱하여 문자열로 상태를 받고, 해당 문자열에 따라 state를 설정하고 이에 맞는 style을 부여한다.
- onClick 이벤트를 사용하여 라우팅과 색 입히는 것을 동시
이 두가지 방법이 떠올랐고, 실행에 옮기고자 하였으나 여러가지 의문이 들었습니다.
window.location.href 파싱
url문자열을 받아오고 파싱을 하는 방법은 가장 떠올리기 쉽고, 직관적인 해결방법입니다. 눈에 보이는 요소를 통해 처리를 하기 때문에 그렇게 생각했던 것 같습니다.
그러나 몇가지 의문이 드는 점 또한 존재했습니다.
- 이전에 query string을 사용 할 때, 문자열 파싱을 이용했는데, 찾아보니 urlSearchParams ~ 속성을 활용하여 파싱하는 것을 학습했고, 이처럼 편한 방법으로 현재 주소 상태를 가져오는 방법이 있을 것 같다.
- 파싱을 하게되면 ‘/’기준으로 파싱을 할 것이다. 지금이야 프로덕트의 depth가 얕아서 ‘/’가 하나지만 추후 여러가지 depth가 생길 수 있음을 고려해야된다.
와 같은 고민을 하게 되었습니다.
이에 두번째 방식인 onClick 이벤트를 사용에 대해서 고민했습니다.
Onclick 이벤트 부여
선택에 대한 근거는 다음과 같았습니다.
어차피 Navbar에서 클릭을 통해 페이지가 전환되야하고, 전환되는 이벤트를 줄 때 같이 style을 부여하는 이벤트만 추가하게되면 해결되는 문제 아닌가? 라는 생각과 함께 진행을 했습니다.
여기서도 추가적인 고민을 했던 것이
- Onclick으로 이벤트를 부여하고 색을 입히면 페이지가 전환될 때 이전에 부여됐던 컴포넌트의 색 클래스를 제거해주는 로직이 필요하지 않나? ex) A화면 : A아이콘(파란색), B아이콘(회색) → B화면: A아이콘(클래스 제거 → 회색) B아이콘(이벤트 추가 → 파란색) 이 과정이 불필요하다고 느껴졌고, 코드가 필요 이상으로 길어질 수 있겠다고 생각했습니다.
- 만일 현재 띄워져있는 페이지를 받는 상태를 이용해서 onclick을 사용한다면, 그래도 state를 써야하므로 이 상태 없이 가능할 수 있지 않을까?
사실 코드 안에 다량의 if문과 다량의 state를 쓰기 싫었습니다.
NavLink
결국 NavigationBar의 본질은 라우팅이라고 생각했고, 라우팅에 관련된 글을 읽어보다가 NavLink에 대해서 발견했습니다.
NavLink가 뭔데요?
<NavLink> is a special kind of <Link> that knows whether or not it is "active".
This is useful when building a navigation menu such as a breadcrumb or
a set of tabs where you'd like to show which of them is currently selected.
It also provides useful context for assistive technology like screen readers.'
- ‘활성화’ 여부를 제공하는 Link의 종류이고, 현재 선택을 보여줘야하는 navigation menu를 만드는데 유용하다. 또한 여러가지 유용한 컨텍스트를 제공한다.
NavLink를 왜 사용했는가?
만일 onclick, link를 사용하여 작업을 하는 경우, 현재의 URL과 이동할 URL을 비교하여 클래스를 추가 혹은 삭제를 해주는 불필요한 로직이 생기게됨.
const prevPath = useLocation();
return (
<Link
to={path}
className={classNames("foo", {
isActive: path === prevPath
})}
>
);
But
NavLink를 사용하면 별도의 처리 로직 없이 isActive 속성을 활용하여 현재 활성화 되어있는지에 대한 여부를 받고, 이에 따른 처리만 해주면 됨.
과 같은 근거로 사용을 했습니다.
실제로 작성한 코드에서 해당 부분에 대한 처리는 다음과 같았습니다.
<NavLink to=path className={({ isActive }) => (isActive ? "foo" : "")}>
언뜻 별 차이가 없어보이고, 결국 isActive 상태 받아서 삼항연산 처리 했을 뿐, 위의 코드와 다를게 없지 않나..?라고 생각이 들기도하지만, 불필요한 prevPath 상태제거와, 직접 비교하는 연산을 제거해서 코드를 간결하게 했다는 점이 긍정적인 요소라고 생각합니다.
- 가장 큰 장점은 한번 설정함으로써 개발자가 불필요하게 현재 경로와 Link에서 사용하는 경로에 대해서 계속해서 신경쓰지 않아도 된다는 점 같습니다.
'Project > Fitory' 카테고리의 다른 글
Fitory - Fitory 검색페이지 개발 기록 & 성능 개선기 (0) | 2022.12.29 |
---|