react에는 named-route 없나요?(Feat. vue에는 있는데..)

2023-06-30


2023-05-05에 작성된 원문을 수정한 버전입니다

vue-router를 사용하는 두 가지 방법

vue에서는 vue-router에서 제공하는 <router-link> 컴포넌트로 페이지 이동을 하려면 크게 두 가지 방법이 있는데, 하나는 해당 페이지의 pathname을 직접 적는 방법과 다른 하나는 router에서 미리 정의해둔 route name을 적는 방법이다.

// 방법 1 <router-link to="/">홈</router-link> <router-link to="/about">어바웃</router-link> // 방법 2 <router-link :to="{name : 'Home'}">홈</router-link> <router-link :to="{name : 'About'}">어바웃</router-link> // 그리고 vue-router에서 미리 route별로 name을 지정해주어야 한다 const routes = [ { path: '/', name: 'Home', component: ..., }, { path: '/about', name: 'About', component: ..., }, ]

하지만 오타가 난다면?

나는 개발할 때 주로 방법 2를 선호하는데 그 이유는 방법 1의 경우에는 경로명을 잘못 입력하더라도 에러로 검출해내지 못하고 클릭하면 /abou페이지로 이동시켜버리는 반면에, 방법 2는 아래와 같이 개발자 도구의 콘솔창에서 에러를 띄워주기 때문이다.

// 방법 1 <router-link to="/">홈</router-link> <router-link to="/abou">어바웃</router-link> // 오타, 에러 발생X // 방법 2 <router-link :to="{name : 'Home'}">홈</router-link> <router-link :to="{name : 'Abou'}">어바웃</router-link> // 오타, 에러 발생함

named route error

방법 1은 오타가 발생하더라도 해당 라우터를 클릭해서 404 페이지가 뜨는 걸 확인하기 전까지는 찾기가 어렵다. 왜냐하면 사용자가 오타를 낸 건지, 아니면 정말로 /abou페이지로 이동하길 원하는지 라우터에게는 알 수 있는 정보가 없기 때문이다.

반면에 방법 2에서는 라우터를 클릭하기 전에도 콘솔창에서 에러를 검출할 수 있다. routes에 들어있는 원소를 하나씩 뒤져보면서 name이 Abou와 일치하는 라우트를 찾아본다. 일치하는 라우트가 없으면 에러로 판별해낼 수 있는 단서가 제공된다는 뜻이다.

이런 식으로 vue 에서는 named-route기반으로 페이지 이동이 가능하기 때문에 예상치 못한 오타 발생시 에러로 검출할 수 있는 반면에 react에서 <Link to={'/about'} 또는 useNavigate훅의 navigate('/about')와 같이 pathname 기반으로만 이동할 수 있다.

따라서 위의 언급한 방법 1처럼 오타로 인한 route 이동을 막을 수 있는 방법은 아직까지는 찾지 못하였다. 타입스크립트로 pathnameenum이나 type으로 변수화시키는 방법이라면 가능할 지도 모르겠다는 생각은 드는데, 실무에서도 그렇게 개발할 지는 모르겠다.


현재 페이지 판별

위 주제와 비슷한 궁금증.

리액트에서는 현재 접속해있는 페이지를 판별하는 방법에 대해서이다. 예를 들어 현재 접속한 페이지와 일치하면 class에 isMatched를 붙여서 하이라이트 스타일을 주는 상황을 생각해보자. vue로 구현한다면 아래와 같다.

<router-link :to={name : "Home"} class="{ matched : $route.name === 'Home'}"> Home </router-link> <router-link :to={name : "About"} class="{ matched : $route.name === 'About'}"> About </router-link>

사실상 스크립트 코드를 하나도 작성하지 않고 template 레벨에서만 현재 라우트 일치 여부를 판별해낼 수 있다.

이걸 react 로 작성해본다면

function Header() { const { pathname: currentPath } = useLocation() const isMatch = (path: string) => { if (currentPath === path) return "matched" } return ( <Nav> <Link to="/" className={currentPath === "/" ? "matched" : ""}> Home </Link> <Link to="/about" className={isMatch("/about")}> About </Link> </Nav> ) }

우선 useLocation훅을 통해서 현재의 pathname을 한번 뽑아와야하며, <Link>에서도 클래스를 동적으로 바인딩 할 때도 삼항연산자로 판별하거나, 코드를 줄이려면 isMatch함수를 하나 선언해서 인자로 현재 <Link>To 값을 그대로 넣어줘야 한다(물론 이건 vue도 마찬가지다).

vue는 template 레벨에서 $route.name 으로 현재 라우트 정보를 한방에 가져올 수 있고, class-binding을 할 때에도 :class={isMatched : someValue} 에서 someValue값이 true면 곧바로 클래스 이름으로 붙일 수 있어 편리하다.

vue는 너한테-이런게-필요할거-같았어 기능(함수)들이 미리 제공되어있는 반면에 react는 너가-직접-구현하렴같은 느낌이다.
react는 기능에 대한 부품들만 던져준다면, vue는 그 부품으로 조립까지 해주는 느낌이랄까? 각 라이브러리가 추구하는 방향성의 차이를 알 수 있는 대목이다.

각자 장단점이 있겠지만, 나 같이 vue를 먼저 익히고 난 뒤에 react에서는 그 기능을 어떻게 구현해야 하는지 찾아보는 입장에서는 조금 답답함이 느껴지는 것도 사실이다.


Profile picture

하주헌 Neon

프론트엔드 개발자입니다. 제가 작성한 코드가 화면에 나타나는 모습을 좋아합니다. 백엔드에도 관심이 많습니다.

Loading script...