1-4. 라우트 속의 라우트

react-router 가 버전 4로 업데이트 되면서 달라진 점 중 하나는, Route 내부에 Route 를 설정하는 방식이 달라졌다는 것 입니다.

이전에는, 다음과 같은 형식으로 라우트를 선언하고:

<Route path="foo" component={Foo}>
    <Route path=":id" component={Bar}/>
</Route>

Foo 컴포넌트에서 props.children 의 자리에 Bar 컴포넌트가 들어가는 형식이였습니다. 그래서 모든 라우트는 최상위에서 정해주어야 했죠.

하지만 이제는 다릅니다. v4 에서는, props.children 을 사용하지 않고 라우트에서 보여주는 컴포넌트 내부에 또 Route 를 사용 할 수 있게 됐습니다. 한번 해볼까요?

먼저 Post 라는 페이지 컴포넌트를 만드세요. 이 컴포넌트에서는 params.id 를 받아와서 렌더링해줍니다.

src/pages/Post.js

import React from 'react';

const Post = ({match}) => {
    return (
        <div>
            포스트 {match.params.id}
        </div>
    );
};

export default Post;

그 다음엔 Posts 페이지 컴포넌트를 만드세요. 이 컴포넌트에 Link 에서 현재 주소 뒤에 id 를 붙여서 이동하도록 설정하세요. 그리고 Link 리스트 하단에는 Route 를 통해 조건에 따라 원하는 결과를 보여주도록 설정하겠습니다.

src/pages/Posts

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;

상단부터 코드 설명을 하겠습니다. Post 컴포넌트를 불러올때 './Post' 에서 바로 불러오는게 아닌 'pages' 를 통해 불러왔습니다. 지금 상황에서는 상대경로에서 불러오는게 더 자연스러울수도 있긴 합니다. 하지만, 우리는 2장에서 코드스플리팅을 해보게 될 텐데, 이 과정에서 페이지를 불러오는 방식이 통일되어야 제대로 작동하므로 pages 에서 불러오도록 설정하였습니다.

Link 를 설정하는 부분에서는, match.url 이 사용되었는데요, 이 url 은 현재의 라우트의 경로를 알려줍니다.

이 부분에서는 그냥 to="/posts/1" 으로 설정을 해도 됩니다. 하지만, 이렇게 하는 경우에 나중에 현재의 라우트 경로가 바뀌게 되면 자동으로 바뀐다는 장점이 있습니다.

하단에 Route 를 설정 할 때 첫번째 라우트는 match.url 로 설정하였습니다. 이 의미는, 포스트의 id 가 주어지지 않았을 때를 의미합니다. 그리고 여기서는 component 대신에 render 가 되었지요? 이 render 는 지금처럼 인라인 렌더링을 가능케 해줍니다.

두번째 라우트에선 현재 라우트의 주소에 :id 가 붙었을 시에 Post 컴포넌트를 보여주도록 설정했습니다.

완성하였다면, 페이지 인덱스를 수정하세요.

src/pages/index.js

export { default as Home } from './Home';
export { default as About } from './About';
export { default as Posts } from './Posts';
export { default as Post } from './Post';

그 다음엔 App 에서 /posts 경로를 위한 라우트를 설정하세요.

src/App.js

import React, { Component } from 'react';
import { Route, Switch } from 'react-router-dom';
import { Home, About, Posts } from 'pages';
import Menu from 'components/Menu';

class App extends Component {
    render() {
        return (
            <div>
                <Menu/>
                <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;

마지막으로, Menu 컴포넌트에서 /posts 로 연결하는 링크를 넣고 잘 작동하는지 확인해보세요.

src/components/Menu.js

import React from 'react';
import { NavLink } from 'react-router-dom';

const Menu = () => {
    const activeStyle = {
        color: 'green',
        fontSize: '2rem'
    };

    return (
        <div>
            <ul>
                <li><NavLink exact to="/" activeStyle={activeStyle}>Home</NavLink></li>
                <li><NavLink exact to="/about" activeStyle={activeStyle}>About</NavLink></li>
                <li><NavLink to="/about/foo" activeStyle={activeStyle}>About Foo</NavLink></li>
                <li><NavLink to="/posts" activeStyle={activeStyle}>Posts</NavLink></li>
            </ul>
            <hr/>
        </div>
    );
};

export default Menu;

헷갈리는 값들

라우트가 받는 props 중에서, 상당히 헷갈리는 값들이 있습니다.

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

비슷한것들 같은데, 대체 어떻게 다를까요?

한번 Post 와 Posts 에서 이 값들을 화면에 렌더링해보겠습니다.

location.pathname 은 현재 브라우저상의 위치를 알려줍니다. 이 값은 어떤 라우트에서 렌더링하던 동일합니다.

match 관련은 설정한 Route 와 직접적으로 관계된 값만 보여줍니다.

  • Posts 를 보여주는 라우트에선 :id 값을 설정하지 않았으니 path 와 url 이 둘다 /posts 입니다.
  • Post 를 보여주는 라우트에선 path 의 경우엔 라우트에서 설정한 path 값이 그대로 나타납니다. url 의 경우엔 :id 부분에 값이 들어간 상태로 나타납니다.

어때요? 이렇게 보니까 더 이상 헷갈리지 않지요?

results matching ""

    No results matching ""