함께 성장하는 프로독학러

3. 라우트 내부의 라우트 본문

Programming/react router_v4

3. 라우트 내부의 라우트

프로독학러 2018. 5. 21. 09:41

안녕하세요, 프로독학러 입니다.


이번 포스팅에서는 라우트 내부에 라우트를 설정하는 방법에 대해서 알아보도록 하겠습니다.

이는 react-router 가 버전 4로 업데이트 되면서 기존의 방식과는 달라진 것이기 때문에 기존 버전을 사용하신 분들이라면 자세히 들여다 보시는 것을 추천드립니다.


* 포스팅의 내용은 Velopert 님의 리액트 라우터 강의를 복습한 내용이므로 Velopert 님의 원본 강의를 듣고싶으신 분들은 아래의 링크를 참조해 주세요.

<Velopert 님의 리액트 라우터 강좌> https://velopert.com/3411


라우트 내부의 라우트


먼저 버전 4 이전에 라우트 내부에 라우트를 설정하는 방법에 대해서 잠깐 살펴 보겠습니다.


1
2
3
<Route path="foo" component={Foo}>
    <Route path=":id" component={Bar}/>
</Route>
cs


이전 버전의 리액트 라우터에서 라우트 안에 라우트를 설정하려면 위의 코드와 같이 Foo 컴포넌트 의 props.children 자리에 Bar 컴포넌트가 위치해야 하는 형식이었습니다. 따라서 모든 라우트는 최상위 컴포넌트에서 지정해주어야 했었습니다.


하지만 버전 4이후에는 props.children 을 사용하지 않고 라우트에서 보여주는 컴포넌트 내부에서 Route 를 사용할 수 있게 되었습니다. 실습을 통해 확인해 보도록 하겠습니다.


Post 라는 page 컴포넌트를 만들어주세요. 이 컴포넌트에서는 params.id 를 받아와서 렌더링 하도록 하겠습니다.


(src/pages/Post.js)

1
2
3
4
5
6
7
8
9
10
11
import React from 'react';
 
const Post = ({match}) => {
    return (
        <div>
            포스트 {match.params.id}
        </div>
    );
};
 
export default Post;
cs


위 코드의 6번째 줄에서 라우트에서 지정한 url 파라메터 id 값을 렌더링 하도록 설정했습니다.


그 다음엔 Posts 페이지 컴포넌트를 만들어 보도록 하겠습니다. 이 컴포넌트에서는 Link 컴포넌트를 통해 현재 주소 뒤에 id 를 붙여 이동하도록 설정하겠습니다. 그리고 Link 컴포넌트(리스트) 하단에는 Route 를 통해 id 파라메터에 따라 post 컴포넌트를 다르게 렌더링하도록 설정하겠습니다.


(src/pages/Posts.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React from 'react';
import { Link, Route } from 'react-router-dom';
import { Post } from 'pages';
 
const Posts = ({match}) => {
    return (
        <div>
           <h2>Post List</h2>
           <ul>
                <li><Link to={`${match.url}/1`}>Post #1</Link></li>
                <li><Link to={`${match.url}/2`}>Post #2</Link></li>
                <li><Link to={`${match.url}/3`}>Post #3</Link></li>
                <li><Link to={`${match.url}/4`}>Post #4</Link></li>
           </ul>
           <Route exact path={match.url} render={()=>(<h3>Please select any post</h3>)}/>
           <Route path={`${match.url}/:id`} component={Post}/>
        </div>
    );
};
 
export default Posts;
cs


코드의 세 번째 줄에서 Post 컴포넌트를 불러올 때, './Post' 로 불러온 것이 아니라 'pages' 를 통해서 불러왔습니다. 상대경로로 불러오는 것이 더 자연스럽게 느껴질 수 있지만, 이는 추후에 다루게 될 코드 스플리팅을 위한 것입니다. 코드 스플리팅을 할 때는 페이지를 불러오는 방식이 통일되어야 하기 때문입니다. 지금 단계에서는 이해되지 않아도 좋으니 추후에 코드 스플리팅을 위한 통일이다 정도로만 생각하고 있으면 됩니다.


10-13번째 줄에서 Link 컴포넌트를 사용할 때, to 속성에 match.url 을 사용하였습니다.

to = '/posts/1' 로 설정해도 되지만, match.url 을 사용하면 현재 라우트 경로가 바뀌더라도 해당 경로를 상대적으로 매치시켜 준다는 장점이 있습니다.


15번째 줄의 라우트의 path는 match.url 로 '/' 와 같습니다. (id 값이 주어지지 않은 상태)


16번째 줄의 라우트의 경로는 현재 경로에 id 파라메터가 붙은 경로로, Post 컴포넌트를 렌더링 합니다. (id 값에 따라 Post 컴포넌트에서 렌더링 하는 값이 달라짐)


여기까지 작성하셨다면 pages 폴더의 index 파일을 수정하겠습니다.


(src/pages/index.js)

1
2
3
4
export { default as Home } from './Home';
export { default as About } from './About';
export { default as Posts } from './Posts';
export { default as Post } from './Post';
cs


그 다음엔 App 컴포넌트에서 /posts 경로를 위한 라우트를 설정해 줍시다.


(src/shared/App.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React, { Component } from 'react';
import { Route, Switch } from 'react-router-dom';
import { Home, About, Posts } from 'pages';
import Header from 'components/Header';
 
class App extends Component {
    render() {
        return (
            <div>
                <Header/>
                <Route exact path="/" component={Home}/>
                <Switch>
                    <Route path="/about/:name" component={About}/>
                    <Route path="/about" component={About}/>
                </Switch>
                <Route path="/posts" component={Posts}/>
            </div>
        );
    }
}
 
export default App;
cs


3번째 줄에서 Posts 컴포넌트를 불러와 16번째 줄에서 라우트로 설정해 주었습니다.


마지막으로, Header 컴포넌트에서 /posts 로 연결하는 링크를 넣고 잘 작동하는지 확인해봅시다.


(src/components/Header.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react';
import { NavLink } from 'react-router-dom';
import './Header.css';
 
const Header = () => {
    return (
        <div className="header">
            <NavLink exact to="/" className="item" activeClassName="active"></NavLink>
            <NavLink to="/about/pro-self-studier" className="item" activeClassName="active">소개</NavLink>
            <NavLink to="/posts" className="item" activeClassName="active">게시판</NavLink>
        </div>
    );
};
 
export default Header;
cs




즉, Posts 라우트 안에서 Post 컴포넌트로 이동하는 라우트를 설정한 것입니다.


비슷해 보이는 props 들


라우트가 기본적으로 전달받는 props 들 중에 비슷하게 느껴지는 세 가지가 있습니다.


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


이 세 값들이 어떻게 다른지 화면에 렌더링하여 확인해 보도록 하겠습니다.


(src/pages/Post.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React from 'react';
 
const Post = ({location, match}) => {
    return (
        <div>
            포스트 {match.params.id}
            <p><strong>location.pathname:</strong> {location.pathname}</p>
            <p><strong>match.path:</strong> {match.path}</p>
            <p><strong>match.url:</strong> {match.url}</p>
        </div>
    );
};
 
export default Post;
cs


(src/pages/Posts.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from 'react';
import { Link, Route } from 'react-router-dom';
import { Post } from 'pages';
 
const Posts = ({location, match}) => {
    return (
        <div>
           <h2>Post List</h2>
           <ul>
                <li><Link to={`${match.url}/1`}>Post #1</Link></li>
                <li><Link to={`${match.url}/2`}>Post #2</Link></li>
                <li><Link to={`${match.url}/3`}>Post #3</Link></li>
                <li><Link to={`${match.url}/4`}>Post #4</Link></li>
           </ul>
           <p><strong>location.pathname:</strong> {location.pathname}</p>
           <p><strong>match.path:</strong> {match.path}</p>
           <p><strong>match.url:</strong> {match.url}</p>
           <Route exact path={match.url} render={()=>(<h3>Please select any post</h3>)}/>
           <Route path={`${match.url}/:id`} component={Post}/>
        </div>
    );
};
 
export default Posts;
cs


브라우저에서 확인해 보면 다음과 같습니다.



Posts 건 Post 건 location.pathname 의 값은 동일합니다.


즉, location.pathname 은 현재 브라우저 상의 위치를 나타내는 props로, 어떤 라우트에서 렌더링 하더라도 동일하게 출력됩니다.


match 값들은 설정한 라우트와 직접적으로 관계된 값만 보여주는 props 입니다.


Posts 를 보여주는 라우트를 설정할 때, path 에 :id 값을 설정하지 않았으므로 path 와 url 이 모두 /posts 입니다. (App 컴포넌트에서 설정한 라우트)


반면 Post 를 보여주는 라우트를 설정할 떄는 path 값에 :id 파라메터를 지정했으므로, path 에는 설정한 그대로 출력되고, url 에는 :id 값이 들어간 상태로 보여지게 됩니다. (Posts 컴포넌트에서 설정한 라우트)


여기까지...


라우트 내부에 라우트를 설정하는 방법과 라우트가 전달받는 props 들 중 헷갈리는 값들을 정리해 보았습니다.


1~3 강까지 리액트 라우터를 사용하는 기본적인 방법에 대해서 알아보았습니다.


다음 포스팅 부터는 SPA 의 단점(트래픽, 로딩속도 등)을 개선하는 코드스플리팅에 대해서 알아보도록 하겠습니다.


감사합니다.


**참고 자료 (항상 감사드립니다)

https://velopert.com/3417


*이 포스팅이 도움이 되셨다면 다녀가셨다는 표시로 공감 부탁드릴게요! (로그인 하지 않으셔도 공감은 가능합니다 ㅎㅎ)

'Programming > react router_v4' 카테고리의 다른 글

2. 라우트 이동  (0) 2018.05.21
1. Route 와 파라미터, 쿼리  (0) 2018.05.18
0. 리액트 라우터 소개, 설치 및 설정  (0) 2018.05.17
Comments