React ] NavLink로 탭 메뉴 클릭 구현하기

히징·2022년 7월 15일
4
post-thumbnail

현재 프로젝트에서 기존에 내가 탭메뉴 컴포넌트를 구현해놨던 방식은 그냥 hover 했을 경우 배경 아이콘의 색이 변경되는 코드이다.
이제 프로젝트가 점점 어느정도 틀이 잡히면서 탭메뉴에 페이지도 연결하고 해당 탭을 클릭했을 경우 배경아이콘의 컬러가 유지되는 기능을 추가하기 위해 NavLink를 사용하게 되었다.

Linkreact-router-dom에서 지원하는 속성으로 라우터를 연결할때 자주 사용해왔을 것이다.

<Link to="/home">home</Link>

리액트 라우터에서 페이지를 이동할 때 Link를 사용하면 브라우저의 주소만 바꾸어 페이지를 새로 불러오지 않은채로 내가 이동하고자 하는 경로에 이동할 수 있다. 즉 a태그로 페이지를 이동할 때 발생하던 새로고침이 일어나지 않는다.

NavLink는 이 Link 태그의 special version 이다.
선택된 요소에 active 클래스가 자동으로 추가되어서 nav스타일링을 원활하게 할 수 있어 아주 편리하다. 지금까지 이런 비슷한 기능을 구현하며 자바스크립트로 selected 클래스를 넣었다 뺐다하는 작업을 했던 걸 생각하면 정말 간단하게 구현 가능할 것 같았다!
이 active 클래스는

className={({isActive}) => (isActive? "red" : "blue")}

이런 방식으로 isActive인 경우 클래스명을 다르게 지정할 수도 있다.

두번째로, activestyle을 지정하여 사용가능하다.

activestyle={color:red} 

이렇게 active 된 스타일을 인라인으로 바꿔 줄 수 있으며 객체를 넣어 전달할 수도 있다.


문제점

이렇게 active 클래스가 내가 선택한 요소에 추가되는 것 까지는 알겠는데.. 너무 유용해보이긴 하는데.. 이걸 내 프젝에서 어떻게 해야할까? 고민에 빠졌다.

마냥 css로 .active { } 해서 요소를 추가하기에는 현재 styled-components로 구현하고 있으며 프롭스를 사용하고 있다. 특히 가상요소인 아이콘의 background를 프롭스로 넣어주고 있기 때문에 더욱 막막했다.

해결

기존코드

<Link to="/homepage">
  <IconNameStyle
   icon={homeIcon}
   hoverIcon={homeIconFill}></IconNameStyle>
</Link>

기존에는 아직 active를 고려하지 않아 Link로 구현하였으며, 그 안에 IconNameStyle 이라는 p 태그 스타일컴포넌트를 만들어주었다.
이미 텍스트로 해당 영역을 알려주기 때문에 아이콘은 사실상 디자인일 뿐이지 필수요소가 아니기에 이미지값이아닌, 스크린리더에 읽히지 않는 가상요소로 주었으며 p태그인 IconNameStyle의 가상요소로 배경 아이콘이 props를 통해 바뀌고 있는 구조이다.

우선 active는 IconNameStyle의 부모요소인 Link의 클래스로 들어가기때문에 IconNameStyle에 있는 가상요소를 건드리기에는 다소 무리가 있다고 판단하였으며 굳이 저걸 Link > IconNameStyle 이렇게 두번 감싸 줄 필요가 있을까? 하는 생각이 들었다.

그래서 Link나 NavLink도 태그이기 때문에 스타일 컴포넌트가 적용되지 않을까 하고 시도해봤더니 오류가 떴다.. 뭔가 될 것 같았는데.
서칭해보던 중 스타일 컴포넌트에서 NavLink를 import 해준다면 스타일링이 가능 하다는 글을 보게 되었고, 작업하는 탭메뉴 컴포넌트 페이지가 아닌, 스타일컴포넌트를 만드는 스타일 페이지에 import 해주었다.

import { NavLink } from 'react-router-dom';

기존의 IconNameStyle 은 NavLinkStyle로 네이밍을 변경해주고,

export const NavLinkStyle = styled(NavLink)`

`

다음과 같이 바꾸어 스타일 컴포넌트를 변경해주었더니 NavLink 태그도 스타일이 잘 이루어졌다!
이제 active class가 추가되었을 경우 스타일을 추가해주기위해

&.active{
  color: #1D57C1;
::before{
  ${(props) => {
    return css`
    background-image: url(${props.hoverIcon});
    `
  }}}
}

다음과 같은 코드를 추가해주었다.
.active::before을 따로 만들지 않고, sass 문법을 사용하여 중첩해서 사용하였다.
스타일 컴포넌트에서 기본적으로 sass문법이 사용하능해서 편리한 것 같다!

이렇게 NavLink를 스타일 컴포넌트해서 불필요한 코드도 줄이고, 간단하게 탭메뉴 선택 기능을 구현 끝 !!

피드는 아직 라우터 연결이 제대로 되어있지 않아서 제외한 완성 결과물 !!

리액트는 너무너무 편한게 많은 것 같다..!! 짱짱

profile
FE DEVELOPER 👩🏻‍💻🤍

0개의 댓글