React.js Router [Outdated]

React.js Router: URL 에 따라서 다른 결과물을 보여주기

이 포스트는 Outdated 되었으니, React-router v3 를 더 자세히 다루는 리액트 프로젝트에서의 라우터, React-router v3 사용하기 를 참고하도록 하자.

이번 포스트는 React.js 의 Router 사용에 대한 내용으로 Router 는 사용자가 요청한 URL 의 서브디렉토리에 따라서 결과물을 렌더링해준다. Apache, nginx등의 웹서버처럼 각 페이지마다 다른 디렉토리 및 파일을 사용하는것과 달리, 라우터를 사용하게되면 처음부터 웹앱에서 사용 할 모든 컴포넌트들을 먼저 불러와두고, 페이지를 이동할 때 마다 그때 그때 페이지를 처음부터 로딩하지 않고 필요한 컴포넌트만 다시 렌더링 한다.(즉, Header 같은 부분처럼 변동이 없는 부분들은 유지되어있다는 의미이다.)

1. React Router 설치하기

NPM 을 통하여 react-router 을 설치한다:
npm install --save react-router

그리고 index.js 의 상단에 다음 코드를 추가한다:
import { Router, Route, browserHistory, IndexRoute } from 'react-router';

App.js의 상단에는 다음 코드를 추가한다.
import { Link } from 'react-router'

2. Route 할 컴포넌트 만들기

이 섹션에서는 라우팅 할 컴포넌트3개를 만들어보겠다 :

  • Home
  • About
  • Articles

편의를 위하여 모두 같은 파일 App.js 에 작성하도록하겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Home extends React.Component {
render() {
return (
<h2>Hey, I am HOME!</h2>
);
}
}

class About extends React.Component {
render() {
return (
<h2>Hey, I am ABOUT!</h2>
);
}
}

class Articles extends React.Component {
render() {
return (
<h2>Hey, I am ARTCILES!</h2>
);
}
}

3. Router Container 컴포넌트 만들기

여기서 컨테이너는, App 컴포넌트이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class App extends React.Component {
render() {
return (
<div>
<ul>
<li><Link to="home">Home</Link></li>
<li><Link to="about">About</Link></li>
<li><Link to="articles">Articles</Link></li>
</ul>
{this.props.children}
</div>
);
}
}
  • LINE 7 – 9: 여기서 를 사용하였습니다. Link 는 Router 에 내장되어있는 컴포넌트중 하나인데요, github에서 렌더링 되는 부분 코드를 살펴보면 다음과 같습니다: return <a {...props} onClick={this.handleClick} /> 결국 그냥 링크를 해주는 a 태그와 같지만 다른점은 클릭했을 때, <a href=".."> 이 태그는 페이지 자체를 리로딩해버리지만, <Link> 는 this.props.children 부분만 리로딩해다.
  • LINE 11: this.props.children 은 따로 설정하는 props 가 아니라, 모든 컴포넌트가 기본적으로 가지고있는 컴포넌트로서, 컴포넌트를 사용 할 때, <Component><...></Component> bold로 표시된 부분에 들어가는 부분이 this.props.children 으로 자동으로 설정된다.

4. ReactDOM 렌더링 및 Router 설정하기

index.js 의 최하단에 이 코드를 삽입한다:

1
2
3
4
5
6
7
8
ReactDOM.render(<Router history = {browserHistory}>
<Route path = "/" component = {App}>
<IndexRoute component = {Home} />
<Route path = "home" component = {Home} />
<Route path = "about" component = {About} />
<Route path = "articles" component = {Articles} />
</Route>
</Router>, document.getElementById('root'));

지금까지 ReactDOM 을 사용해 컴포넌트를 렌더링 할 때, 바로 <App…. /> 형태로 해왔지만 라우터를 사용할 땐 <Router …> 형태를 사용합니다. 여기선 App 컴포넌트가 Router의 props로 있는 셈이다.
Route 는 클라이언트상에서 페이지를 라우팅 할 주소를 정의해준다.
browserHistoy 를 사용함으로서, 뒤로가기를 해도 페이지가 새로 리로딩되지 않고 필요한부분만 리렌더링하게끔 해준다.
IndexRoute 의 Index 가 의미하듯, 라우터의 첫 페이지를 정의해준다.

5. 서버 사이드 설정

지금까지 작성한 코드를 저장하고 브라우저상에서 방금 만든 페이지를 열어보자.
Link 들을 클릭해보면 페이지를 라우팅하는데는 문제가없지만 http://localhost/home 와 같이 직접 주소를 입력해주면 “Cannot GET /home” 라는 오류를 반환하게 된다.
해당 주소를 서버에 요청하면 서버쪽 라우터에서 먼저 연결할 곳이 있는지 확인해보고 없기 때문에 이런 오류가 발생한다.
이를 위해 서버에서 따로 설정을 해주어야하는데, 지금 공부하면서 사용하는 webpack 개발서버는, webpack.config.js 파일에 코드 한줄을 추가해주면 해결된다.

1
2
3
4
5
devServer: {
inline: true,
port: 7777,
historyApiFallback: true
},

4번줄인 historyApiFallback을 활성화 해주면 이 문제가 해결된다.

하지만, express를 사용하는경우에는 다음과 같이 작성하면 된다.

1
2
3
4
5
var app = express();

app.get('*', function (request, response) {
response.sendFile(path.resolve(__dirname, 'public', 'index.html'))
});

참조

공유하기