Routes.js 작성하기

JHyeon·2020년 12월 20일
0

React

목록 보기
2/2
post-thumbnail

리액트 라우트를 사용하면서 Routes.js 파일을 여러번 개선하였다. 그 과정을 정리하고자 한다.

이 글의 코드 개선은 짧은 경험에서 나온 결과물이므로 정답이 아닐 수 있습니다. 더 좋은 방법이 있거나 잘못된 방향으로 코드 개선이 이루어졌다면 그에 관한 소중한 의견 부탁드립니다.

Routes.js 단계별 개선

1단계 : 일단 라우팅을 하자

<Router>
  <Switch>
    <Route exact path="/Home" component={Home}></Route>
    <Route exact path="/Signup" component={Signup}></Route>
    <Route exact path="/Login" component={Login}></Route>
    <Route exact path="/ItemList" component={ItemList}></Route>
    <Route exact path="/ItemDetail" component={ItemDetail}></Route>
  </Switch>
</Router>

경로에 따라 보여지는 컴포넌트를 다르게 하는 기본적인 리액트 라우트 라이브러리의 기능을 구현한 코드이다.

2단계 : 항상 보이는 공통 컴포넌트는 분리하자

<Router>
  <Header />
  <AsideMenu />
  <Switch>
    <Route exact path="/Home" component={Home}></Route>
    <Route exact path="/Signup" component={Signup}></Route>
    <Route exact path="/Login" component={Login}></Route>
    <Route exact path="/ItemList" component={ItemList}></Route>
    <Route exact path="/ItemDetail" component={ItemDetail}></Route>
  </Switch>
  <Footer />
</Router>

많은 웹 페이지에는 Header와 Footer가 존재한다. 혹은 사이드 메뉴가 있는 경우도 있다. 이런 공통 컴포넌트는 해당 사이트 내에서 라우팅을 할 때 공통적으로 항상 보여지는 컴포넌트로 위 코드와 같이 분리하여 항상 보여지는 식으로 할 수 있다.

3단계 : 페이지 별로 공통 컴포넌트 숨기기

const HIDE_ASIDE_MENU = ["/Login", "/Signup"];
const aside = HIDE_ASIDE_MENU.includes(window.location.pathname) ? null : <AsideMenu />;

class Routes extends Component {
  render() {
    return (
      <Router>
        <Header />
        {aside}
        <Switch>
          <Route exact path="/Home" component={Home}></Route>
          <Route exact path="/Signup" component={Signup}></Route>
          <Route exact path="/Login" component={Login}></Route>
          <Route exact path="/ItemList" component={ItemList}></Route>
          <Route exact path="/ItemDetail" component={ItemDetail}></Route>
        </Switch>
        <Footer />
      </Router>
    );
  }
}

하지만 경우에 따라 공통 컴포넌트를 숨기고 싶은 경우도 있다. 만약 로그인 페이지와 회원가입 페이지에서는 사이드 메뉴 AsideMenu를 숨기고 싶을 때 위와 같이 코드를 작성할 수 있다. 만약 추가적인 변경사항이 있을 경우 HIDE_AISDE_MENU 변수를 수정하기만 하면 된다.

4단계 : 잘못된 path 처리하기, 404 페이지

const HIDE_ASIDE_MENU = ["/Login", "/Signup", "/ItemCart"];
const aside = HIDE_ASIDE_MENU.includes(window.location.pathname) ? null : <AsideMenu />;

class Routes extends Component {
  render() {
    return (
      <Router>
        <Header />
        {aside}

        <Switch>
          <Route exact path="/Home" component={Home}></Route>
          <Route exact path="/Signup" component={Signup}></Route>
          <Route exact path="/Login" component={Login}></Route>
          <Route exact path="/ItemList" component={ItemList}></Route>
          <Route exact path="/ItemDetail" component={ItemDetail}></Route>
          <Route exact path="/ItemCart" component={ItemCart}></Route>
          <Route exact path="/Payment" component={Payment}></Route>
          <Route component={NotFound} />
        </Switch>
        <Footer />
      </Router>
    );
  }
}

추가적으로 다른 페이지도 추가하고 마지막으로 404 페이지를 구현한 코드이다. 사용자가 주소이름을 잘못 입력하거나 어떠한 이유로 잘못된 path로 접근하려고 할 경우 NotFound 라는 컴포넌트가 Switch 내에서 보여진다. 이는 위에서부터 차례대로 해당하는 페이지가 있는지 탐색한 후 일치하는 경로가 없을 때 마지막으로 NotFound 페이지가 보이는 것이다. 이 컴포넌트에서 404 NOTFOUND에 대한 페이지 구성을 하면 될 것이다.

라우트가 받는 값

라우트가 받는 값에 대해 이전 글에서 조금 다룬 적이 있다. 라우터가 받는 histoyr, location, match의 내부 값들 중 아래 세 가지 값을 살펴보자.

  • location.pathname
  • match.path
  • match.url

이 세가지 이름만 보면 다 비슷해 보인다. 콘솔창에 값을 찍어보는 것이 가장 정확할 것이다. 그래서 현재 진행중인 마켓컬리 클론 팀 프로젝트에서 한번 찍어보았다!

console.log(`location.pathname: ${this.props.location.pathname}`);
console.log(`match.path: ${this.props.match.path}`);
console.log(`match.url: ${this.props.match.url}`);

하지만 결과는 처참히 같았다. 그러나 아직 방심하긴 이르다. 우리에겐 구글이 있다.

  • location.pathname : 현재 브라우저상의 위치를 알려준다. 즉 /ItemDetail 이라는 위치를 나타낸다.
  • match 에서는 해당 Route와 직접적으로 관계된 값만 보여준다. match.path 에서는 /ItemDetail/:id 와 같이 동적 라우팅을 구현했을 때 location.pathname 과 차이가 나타나게 된다. match.url 에서는 그 동적 라우팅에서 id의 값이 주어져있다면 /ItemDetail/3 처럼 나타나게 된다.

즉, 내가 console.log 로 확인한 컴포넌트는 아직 동적 라우팅으로 구현된 페이지가 아니기에 똑같이 나타난 것이다. 정리하자면 아래와 같다.

  • location.pathname : /path
  • match.path : /path/:id
  • match.url : /path/43
profile
The only thing that interferes with my learning is my education.

0개의 댓글