티스토리 뷰

React.JS

react-router는 create-react-app로 react 프로젝트를 생성하여 진행합니다.

1. create-react-app

create-react-app 설치는 [React.JS] CodePen, create-react-app으로 React.JS 개발하기 참고 바랍니다.
create-react-app이 설치가 완료 되었다면, react 프로젝트를 생성합니다.

create-react-app hello-react-router

2. react-router-dom 설치하기

npm install --save react-router-dom

3. react-router 적용하기

create-react-app으로 프로젝트를 만들고, react-router-dom 모듈을 설치했다면, 기본 준비는 끝이 납니다.
이번 프로젝트에서 만들 라우터는 4가지 입니다.

  • /: Home 컴포넌트를 보여줍니다.
  • /about: About 컴포넌트를 보여줍니다.
  • /posts: Post 컴포넌트를 보여줍니다.
  • /login: Login 컴포넌트를 보여줍니다.

라우트 컴포넌트들은 routes 폴더를 만들어 그 밑에 정의하였습니다.

Header 컴포넌트

react-router을 만들기 전에, 이동할 url을 화면으로 보여줄 Header 컴포넌트를 만들어 보겠습니다.
src 폴터 밑에 components 폴더를 생성하여, compontents 폴더 밑에 Header.js 파일을 만듭니다.

src/components/Header.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';

class Header extends Component {
    render() {
        return (
            <div>
                <Link to="/">홈</Link>
                <Link to="/about/beomy">소개</Link>
                <Link to="/Posts">포스트</Link>
                <Link to="/login">로그인</Link>
            </div>
        );
    }
}

export default Header;
  • 2번 줄, react-router-dom에서 Link 컴포넌트를 import 합니다.
  • 8~10번 줄, Link를 to에 정의된 값으로 url을 변경하여 페이지를 이동시켜 줍니다. (실제로 페이지가 이동 되는 것은 아니고 다시 그려줍니다.)
  • 9번 줄, /about/beomy로 url 파마미터를 지정하였습니다. Router 설정에서 :username으로 url 파라미터 라우터 설정을 하였고, 자세한 설명은 About 컴포넌트를 이야기할 때 함께 이야기 하겠습니다.

Router 설정

이제 Header 컴포넌트에서 클릭되어 온 url에 어떠한 컴포넌트를 보여 줄 것인지 정의해야 합니다.

src/App.js를 아래 코드와 같이 수정합니다.

src/App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Header from './components/Header';

import Home from './routes/Home';
import About from './routes/About';
import Posts from './routes/Posts';
import Login from './routes/Login';
import NoMatch from './routes/NoMatch';

class App extends Component {
  render() {
    return (
      <Router>
        <div>
          <Header />
          <Switch>
            <Route exact path="/" component={Home}/>
            <Route path="/about/:username" component={About}/>
            <Route path="/posts" component={Posts}/>
            <Route path="/login" component={Login}/>
            <Route component={NoMatch}/>
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;
  • 2번 줄, react-router-dom에서 BrowserRouter, Route, Switch를 import로 가져옵니다. BrowserRouter는 Router라는 이름으로 사용하기 위해 'as'를 사용하였습니다. ([자바스크립트] ES6(ECMA Script6) - export, import 참고)
  • 3번 줄, Header 컴포넌트를 import로 가져옵니다.
  • 5~9번 줄, url에 맞는 컴포넌트를 보여주기 위해 라우터 컴포넌트들을 import로 가져옵니다.
  • 10번 줄, 어떠한 Route도 설정되지 않았을 경우 보여줄 컴포넌트를 import로 가져옵니다.
  • 16번 줄, Header 컴포넌트를 보여줍니다.
  • 18~22번 줄, Route 설정을 합니다. path에 정의된 경로로 들어올 경우, component에 정의된 컴포넌트를 보여줍니다.
  • 18번 줄, exact는 만약 /about으로 들어올 경우, /와 /about이 모두 매칭 되기 때문에 Home 컴포넌트와 About 컴포넌트 두개가 보이게 됩니다. exact를 사용하면, 매칭이 될 경우 하위 라우트 설정을 보지 않게 됩니다.
  • 19번 줄, :username으로 url 파마미터를 설정하였습니다.
  • 22번 줄, Route가 설정되지 않을 경우, component에 정의된 컴포넌트를 보여줍니다. 22번 줄 처럼 사용하기 위해서는 17, 23번 줄 처럼 Route 컴포넌트를 Switch 컴포넌트 안에 정의 해야 합니다. 이 기능을 사용하여 404 페이지를 커스텀하게 정의할 수 있습니다.

Header 컴포넌트는 항상 보이게 되고, 그 밑으로 url에 맞게 Component가 선택되어 보이게 됩니다.

Home 컴포넌트

/로 접근할 경우 보이게 되는 메인 컴포넌트 입니다.

src/routes/Home.js

import React, { Component } from 'react';

class Home extends Component {
    render() {
        return (
            <div>
                홈
            </div>
        );
    }
}

export default Home;

About 컴포넌트

scr/routes/About.js

import React, { Component } from 'react';

class About extends Component {
    render() {
        return (
            <div>
                {this.props.match.params.username} 의 소개
            </div>
        );
    }
}

export default About;
  • 7번 줄, this.props.match.params.username를 보여줍니다. (App.js의 17번 줄에서 설정한 username 필드명으로 값이 내려옵니다.)

* 참고

크롬의 React 개발자 모드로 props.match.params를 확인 해 보면 아래 그림과 같습니다.

this.props.match.params
this.props.match.params

Posts 컴포넌트

scr/routes/Posts.js

import React, { Component } from 'react';
import { Route, Link } from 'react-router-dom';

class Post extends Component {
    render() {
        return (
            <div>
                <p>title: {this.props.match.params.title}</p>
                <p>id: {new URLSearchParams(this.props.location.search).get('id')}</p>
            </div>
        );
    }
}

class Posts extends Component {
    render() {
        return (
            <div>
                <p>포스트</p>
                <Link to="/posts/first?id=1">First</Link>
                <Link to="/posts/second?id=2">Second</Link>
                <Link to="/posts/third?id=3">Third</Link>
                <Route 
                    path="/posts/:title"
                    component={Post} />
            </div>
        );
    }
}

export default Posts;
  • 20~22번 줄, Link를 to에 정의된 값으로 url을 변경하여 페이지를 이동시켜 줍니다. to에 정의된 url은 url 파마리터와 쿼리 파라미터가 추가된 url입니다.
  • 23~25번 줄, 서브 라우터를 설정합니다.
  • 4~13번 줄, 서브 라우터가 출력하는 컴포넌트 입니다. Post 컴포넌트는 서브 라우터가 출력하는 컴포넌트입니다.
  • 8번 줄, url 파라미터를 출력합니다.
  • 9번 줄, 쿼리 파라미터를 출력합니다. JavaScript가 제공하는 URLSearchParams 함수를 사용하여 쿼리 파라미터를 파싱하였습니다.

* 참고

About 컴포넌트에서 url 파라미터를 얻는 방법을 설명하였습니다. 쿼리 파라미터를 얻는 방법은 props.location.search를 이용해야 합니다.

크롬의 개발자 모드로 props.location를 확인 해 보면 아래 그림과 같습니다.

props.location
props.location

Login 컴포넌트

이 컴포넌트는 로그인이 안되어 있을 경우 다른 페이지로 redirect 시켜주는 예를 설정하기 위해 작성한 컴포넌트 입니다.

로그인 여부를 체크하는 플래그를 두고, 그 플래그의 값에 따라 redirect 여부를 결정합니다.

src/routes/Login.js

import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';

class Login extends Component {
    isLogin = false;

    render() {
        return (
            <div>
                {
                    !this.isLogin && <Redirect to="/"/>
                }
                로그인 되었습니다.
            </div>
        );
    }
}

export default Login;
  • 2번 줄, react-router-dom에서 Redirect 컴포넌트를 import 합니다.
  • 5번 줄, 로그인 상태를 나타내는 임의의 플러그를 선언하였습니다.
  • 11번 줄, isLogin이 false일 경우 Redirect 컴포넌트 정의 하여 "/"로 redirect 하도록 작성하였습니다. isLogin이 true일 경우 로그인 되었습니다. 라는 문구가 보이게 됩니다.

NoMatch 컴포넌트

NoMatch 컴포넌트는 정의되지 않은 url로 접근 할 경우 보여주는 컴포넌트 입니다. 예를 들어 /test url을 라우팅 설정이 되어 있지 않기 때문에, /test로 접근 할 경우 NoMatch 컴포넌트를 보여주게 됩니다.

src/routes/NoMatch.js

import React, { Component } from 'react';

class NoMatch extends Component {
    render() {
        return (
            <div>
                404
            </div>
        );
    }
}

export default NoMatch;

NoMatch 컴포넌트
NoMatch 컴포넌트

4. Header 컴포넌트 꾸미기

Header 컴포넌트를 조금 꾸며 보도록 하겠습니다.

Header.css 적용하기

아래과 같이 Header.css 파일을 작성합니다.

src/components/Header.css

.header {
    background: #5c7cfa;
    display: table;
    table-layout: fixed;
    width: 100%;
}

.item {
    text-align: center;
    padding-top: 1rem;
    padding-bottom: 1rem;
    display: table-cell;
    color: white;
    text-decoration: none;
    font-size: 1.1rem;
}

.item:hover {
    background: #748ffc;
}

.item:active, .item.active {
    background: white;
    color: #5c7cfa;
}

CSS 파일을 작성하였으니, Header 컴포넌트에 적용해 봅시다.

src/components/Header.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import './Header.css';

class Header extends Component {
    render() {
        return (
            <div className="header">
                <Link to="/" className="item">홈</Link>
                <Link to="/about/beomy" className="item">소개</Link>
                <Link to="/Posts" className="item">포스트</Link>
                <Link to="/login" className="item">로그인</Link>
            </div>
        );
    }
}

export default Header;
  • 3번 줄, CSS 파일을 import 합니다.
  • 8~12번 줄, class를 추가하여 CSS를 적용합니다.

액티브 라우터 스타일 설정하기

현재 활성화된 라우터의 스타일을 적용하기 위해서 NavLink를 사용해 보겠습니다.

import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import './Header.css';

class Header extends Component {
    render() {
        return (
            <div className="header">
                <NavLink exact to="/" className="item" activeClassName="active">홈</NavLink>
                <NavLink to="/about/beomy" className="item"activeClassName="active">소개</NavLink>
                <NavLink to="/Posts" className="item" activeClassName="active">포스트</NavLink>
                <NavLink to="/login" className="item" activeClassName="active">로그인</NavLink>
            </div>
        );
    }
}

export default Header;
  • 2, 9~12 번 줄, Link 컴포넌트를 NavLink 컴포넌트로 변경하여 줍니다.
  • 9~12 번 줄, activeClassName attribute에 활성화 될 경우 적용될 스타일 클래스를 선언해 줍니다.
  • 9번 줄, exact를 사용하였는데, 이유는 Router 설정시 exact를 사용했던 이유와 동일 합니다.
    예를 들어 /about로 접근했다면 /와 /about 모두 만족하기 때문에 /와 /about 모두 active 스타일이 적용이 됩니다. 하지만 exact를 사용하면, 어떤 NavLink에서 조건을 만족할 경우 다음으로 오는 NavLink에는 active 스타일이 적용되지 않게 됩니다.

5. 소스

소스는 https://github.com/beomy/hello-react-router 에서 확인 할 수 있습니다.

참고

'React.JS' 카테고리의 다른 글

[React.JS] Redux 예제로 살펴보기  (12) 2017.05.04
[React.JS] Redux 소개  (0) 2017.05.03
[React.JS] Composition VS Inheritance  (0) 2017.04.25
[React.JS] Lifting State Up  (0) 2017.04.24
[React.JS] Forms  (0) 2017.04.22
댓글
공지사항
최근에 올라온 글