ㄷㅣㅆㅣ's Amusement

[React] Node.js + React -- 3. 라우팅(routing) 본문

Programming/React

[React] Node.js + React -- 3. 라우팅(routing)

ㄷㅣㅆㅣ 2017. 4. 14. 11:11

[React] Node.js + React -- 3. 라우팅(routing)

반응형


포스팅 1,2를 하는데에 30분이 채 걸리지 않았으리라 믿어 의심치 않는다.

일단 환경까지 구축했으니... 디폴트 뷰 말고 react를 이용해서 멋드러진(물론 비교대상은 디폴트뷰)를 만들어보자. 그럼 한시간쯤 될듯?


1. react-router

- routing은 문자 그대로 path를 설정해주는 것이다. 예를들어 ("localhost:3000/", "localhost:3000/about", "localhost:3000/404"등 주소에따라 페이지를 다르게 가져가고싶은 경우 설정한다. express로하면 이동할때마다 깜박깜박해서 react-router를 사용했다.

1
$ npm install react-router@3 --save
cs

- 위의 커맨드를 날리면 react-router를 어플리케이션에 설치하게되고, package.json에도 해당 모듈을 등록한다.


2. package.json

- package.json은 node로 만든 어플리케이션이 어떤 모듈을 필요로 하는가에 대해서 JSon 형태로 기술되어있는 파일이다. ("npm install"시 "--save"옵션을 주면 설치와 동시에 이 파일에도 써준다.)

- 현재 react-router는 v4까지 나온 상태지만, 아직 안정화가 되기에는 시간이 필요하므로 v3으로 제작해본다. ("@3"을 붙이면 알아서 v3중 최신을 설치한다)

- react-router v4는 나중에 따로 포스팅...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "name""nodereact",
  "version""0.1.0",
  "private"true,
  "dependencies": {
    "react""^15.5.4",
    "react-dom""^15.5.4",
    "react-router""^3.0.5"
  },
  "devDependencies": {
    "react-scripts""0.9.5"
  },
  "scripts": {
    "start""react-scripts start",
    "build""react-scripts build",
    "test""react-scripts test --env=jsdom",
    "eject""react-scripts eject"
  }
}
cs


3. 어플리케이션 구조



4. 컴포넌트 정리

- 우리는 점차 여러 페이지를 만들어 나갈 것이기 때문에 App.js를 ./src 바로 밑에 넣어는것은 바람직해보이지 않는다.  따라서 routing에 의해 결정되는 페이지는 ./src/routes 폴더 밑에 두도록 해보자.

- 이때, 폴더로 나누고 index.js로 하면 나중에 import할 때 폴더명까지만 써주면 된다. (./src/routes/home/index.js -->  ./src/routes/home만 해도 됨)

1
2
3
4
$ mkdir -p routes/Welcome
$ mv App.js ./routes/Welcome/index.js
$ mv App.css ./routes/Welcome/style.css
$ mv logo.svg ./routes/Welcome/logo.svg
cs


5. 라우팅

- App.js에 만들어진 react code를 렌더링할 수 있었던 이유는 다음과 같이 src/index.js에서 무조건 App을 렌더링하도록 되어있기 때문이다.

1
2
3
4
5
6
7
8
9
10
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
 
ReactDOM.render(
  <App />,
  document.getElementById('root')
);
cs


- 이제 상위 노드로서 존재하는 src/App.js를 새로 생성한다. (기존에 있던건 route폴더로 옮겼다.)

1
2
3
4
5
6
7
8
9
10
11
12
// src/App.js
import React, {Component} from 'react';
 
export default class App extends Component {
    render() {
        return (
            <div>
                {this.props.children}
            </div>
        );
    }
}
cs


- 그리고 '/'일 경우에는 기존의 Welcome페이지를, 그 외의 것은 NotFound를 출력하는 페이지를 띄우도록 src/index.js를 수정해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
 
import App from './App';
import Welcome from './routes/Welcome';
import About from './routes/About';
import NotFound from './routes/404';
 
import './index.css';
 
ReactDOM.render(
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <IndexRoute component={Welcome}/>
<Route path="/about" component={About}/>
      <Route path="*" component={NotFound}/>
    </Route>
  </Router>,
  document.getElementById('root')
);
cs

- 각자가 생각하는 주소에 (ex. /main, /login 등)라우팅하려면 15번째줄 다음에 등록하면 된다. (ex. <Route path="/main" component={Main}>)

- <IndexRoute>는 '/'이후에 아무 주소가 오지 않는 경우에 띄울 페이지를, <Route path="*",,,>는 상위에서 정의되지 않은 모든 주소에 공통으로 띄울 페이지를 나타낸다. (여기서는 정의되어있지 않는것은 없는 페이지라고 간주.)


- src/index.js의 8번째줄에 보이는 About과 NotFound는 직접 만들어줘야한다.

1
2
3
4
5
6
7
8
9
10
11
12
// src/routes/404/index.js
import React, { Component } from 'react';
 
export default class NotFound extends Component {
  render() {
    return (
      <div >
        <h1> 404 Not Found </h1>
      </div>
    );
  }
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
// src/routes/About/index.js
import React, { Component } from 'react';
 
export default class NotFound extends Component {
  render() {
    return (
      <div >
        <h1><a href="http://www.childc.co.kr" title="ㄷㅣㅆㅣ's Amusement로 가기">I am Childc, come to my blog!! </a></h1>
      </div>
    );
  }
}
cs


6. 헤더를 만들어 예쁘게 라우팅

- react-router는 Link 기능도 제공한다. 때문에 컨테이너로 그 어떤 값도 전달할 필요 없이 무작정 사용해도 OK.

- 다음의 코드는 react 문법이 조금 들어갔는데, 이부분은 나중에 react문법을 포스팅 하면서 다룬다. (더이상의 자세한 설명은 생략한다)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// src/Header.js
import React, { Component } from 'react';
import { Link } from 'react-router';
import './Header.css';
 
export default class Header extends Component {
    MenuItem = function(children, target) {
        return (
            <Link to={target} className="menu-item">
                {children}
            </Link>
        );
    }
 
    render() {
        return (
            <div>
                <div className="title"> childc's react </div>
                <div className="menu">
                    {this.MenuItem('Welcome', '/')}
                    {this.MenuItem('About', '/about')}
                    {this.MenuItem('NotFound', '/*')}
                </div>
            </div>
        );
    }
    
}
cs


- 헤더모양은 간단한 css작성만으로도 About에서 보이는 허접한 모양과 달리 그럴싸하게 표현할 수 있다. (나의 미적 감각은 일반적이지 않다는것은 함정)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// src/Header.css
.title {
    width: 100vw;
    height: 3.5rem;
    line-height: 3.5rem;
    color: white;
    background-color: #222222;
    font-size: 1.5rem;
    font-family: monospace;
    font-weight: bold;
    text-align: center;
}
.menu {
    height: 2.5rem;
    background-color: #282F38;
}
.menu-item {
    display: inline-block;
    width: 33.3%;
    line-height: 2.5rem;
    color: white;
    font-size: 1.3rem;
    font-family: monospace;
    text-align: center;
    cursor: pointer;
    transition: background-color 0.5s;
    text-decoration: none;
}
.menu-item:hover {
    background-color: #495057;
}
.menu-item:active, .menu-item.active {
    background-color: #08123b;
}
cs


- 최종적으로 최상위 컨테이너(src/App.js)에 헤더를 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/App.js
import React, {Component} from 'react';
import Header from './Header';
 
export default class App extends Component {
    render() {
        return (
            <div>
                <Header />
                {this.props.children}
            </div>
        );
    }
}
cs


6. 결과물

- 늘 그렇듯 커맨드를 날린다.


$ npm start
cs


- 헤더의 그 무엇을 클릭하더라도 깜박임은 없다. (물론 브라우저에서 경로를 입력한 경우는 여전이 깜박인다. 그런데 이런 경우는 발생하지 않을 것이므로 처리하지 않음)



반응형
Comments