[미니펫피] Routing 작업 (수정중)

In9_9yu·2021년 9월 22일
1

미니펫피

목록 보기
2/2
post-thumbnail

Routing

내가 했던 라우팅 작업을 요약하자면 다음과 같다. (써놓고 보니 별거 없다.)

  • 새로운 페이지가 추가되었을 때, 그에 맞는 경로를 만들어주고 화면 연결하기
  • Router의 성격에 따라 Public RouterPrivate Router로 구분하여 원하는 기능을 동작하게 하기.

React 자체에서 따로 route 기능을 제공하지 않기 때문에 react-router-dom이라는 라이브러리의 도움을 받았다.

내가 겪었던 문제들

Private Public Route

유저의 현재 상태에 따라 접근 가능한 경로와, 그렇지 않은 경로가 결정된다. 아래의 예시를 보면 더 명확하다.

  • 로그인 하지 않은 상태 : 글쓰기, 글 수정하기 등등
  • 로그인 한 상태 : 회원가입, 로그인 등등

위 같은 경우를 처리하기 위해서 react-router-dom 라이브러리에 있는 Route를 wrapping 하는 컴포넌트(?)를 작성하였다. 역시나 구글은 모든 것을 다 알려준다.

PrivateRoute

export const PrivateRoute = ({ component: ComponentName, ...rest }: RouteModel) => {
  const { id } = useAuth(); // 유저 정보 뽑아오는 부분

  return <Route {...rest} render={(props) => (id ? <ComponentName {...props} /> : <Redirect to="/"/> )} />;
};

PrivateRoute같은 경우는 자신의 로그인 정보가 있어야만 접근 가능한 경로에 적용해 주었다.

  • component : Route에서 경로가 맞으면 보여줄 컴포넌트를 입력하는 부분이다.

  • ...rest : 나머지 props들

  • useAuth : redux store에서 자신의 정보를 뽑아주는 역할을 하는 hook

흐름은 간단하다.

  1. useAuth에서 자신의 id를 가져온다.
  2. 자신의 정보가 있다면, 접근할 수 있으므로 보여주고자 하던 Component를 return 한다.
  3. 자신의 정보가 없다면 (undefined or null), Redirect를 통해 기본 경로("/") 로 보내준다.

PublicRoute

export const PublicRoute = ({ component: ComponentName, restricted = false, ...rest }: RouteModel) => {
  const { id } = useAuth();

  return <Route {...rest} render={(props) => (id && restricted ? <Redirect to="/" /> : <ComponentName {...props} />)} />;
};

PrivateRoute와 다르게, 하나의 restricted라는 prop을 하나 더 받는다. 그 이유는 PublicRoute로 접근하는 경우는 좀 더 많은 경우가 존재하기 때문이다. 로그인 페이지의 예를 들어보자.

  • 로그인을 한 경우 : 로그인 페이지로 이동해서는 안된다.
  • 로그인을 하지 않은 경우 : 로그인 페이지로 이동 할 수있다.

위와 같은 경우처럼, 로그인을 한 여부에 따라 접근할 수 없는 경우가 있기 때문에 restricted라는 props를 받아, 로그인 한 경우 접근을 제한시키도록 설정했다.

App.route

Routing 순서

새로운 경로를 추가할 때, Switch가 url이 Route와 가장 첫번째로 매치되는 경우를 렌더링하다보니, 꽤나 자주 App.tsx 부분을 손대야 하는 경우가 생겼다.
사실 제대로 설정안하고, 이리저리 바꾸면 제대로 동작해서 그냥 했을지도...

이 참에 어떻게 해야 제대로 동작하는 지 정리해보고자 한다.

근데 아무리 찾아봐도 뭘 기준으로 매칭을 하는지 전혀 알 수가 없었다. 공식문서문서에서 이리저리 읽어보다가 간신히 발견한 것 같다.

아래의 링크를 참조하였다. 아흑흑... 다른거도 해야해서 잠시 패쓰...

정신을 다시 차리고서,어떤 기준으로 path를 match하는지 너무 궁금해졌다. 단순히 정규표현식으로만 match를 한다면 '/about/:id'와 '/about'은 매치가 되지 않아야 할텐데...

한참동안 정규표현식의 늪에 빠져있다가, 역시 공식문서에는 답이 있더라.

Route.js코드를 까보니, 그 안에 matchPath라는 부분이 있었다.즉, 새로운 url로 접근을 할 때마다 모든 Route마다 matchPath를 거쳐서 match되는 것이 존재하면, 그 부분을 rendering 하는 것이었다.

이제 그걸 Switch로 막는 것이고.
그렇기 때문에 가장 nested된 url을 상단에 두고, 하위로 내려갈 수록 점점 root와 근접해지는 방식으로 순서를 두면 될 듯 싶다.

profile
FE 임니다

0개의 댓글