1-2. Route 와 파라미터

기본 라우트 준비하기

자 그럼 우리의 첫 라우트 Home을 만들어보겠습니다.
이 라우터는 주소에 아무 path 도 주어지지 않았을 때 기본적으로 보여주는 라우트입니다.

src/pages/Home.js

import React from 'react';

const Home = () => {
    return (
        <div>
            <h2></h2>
        </div>
    );
};

export default Home;

그리고 같은 형식으로 About 도 만드세요. 이 페이지는 /about 경로로 들어왔을 때 보여줄 페이지입니다.

src/pages/About.js

import React from 'react';

const About = () => {
    return (
        <div>
            <h2>About</h2>
        </div>
    );
};

export default About;

이제 이 컴포넌트를 불러와서 한 파일로 내보낼 수 있도록 인덱스를 만들어주세요.

src/pages/index.js

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

라우트 설정하기

자 이제 라우트에 맞춰서 컴포넌트를 보여줍시다. App 컴포넌트를 다음과 같이 작성하세요.

src/App.js

import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import { Home, About } from 'pages';


class App extends Component {
    render() {
        return (
            <div>
                <Route exact path="/" component={Home}/>
                <Route path="/about" component={About}/>
            </div>
        );
    }
}

export default App;

라우트를 설정 할 때에는 Route 컴포넌트를 사용하고, 경로는 path 값으로 설정합니다.

첫번째 라우트 / 의 경우에는 Home 컴포넌트를 보여주게 했고, 두번째 라우트 /about 에서는 About 컴포넌트를 보여주게 했습니다.

첫번째 라우트의 경우엔 exact 가 붙어있지요? 이게 붙어있으면 주어진 경로와 정확히 맞아 떨어져야만 설정한 컴포넌트를 보여줍니다.

먼저 우리의 라우트가 제대로 보여지는지 확인하세요.

Home 이 잘 보여졌다면 /about 경로로 들어가보세요.

잘 보여졌죠? 지금의 경우에는 개발서버쪽에서 historyApiFallback 설정을 통하여 어떤 요청으로 들어오던 저희 어플리케이션이 불러와져있는 index.html 을 보여주도록 설정하기 때문입니다.

링크를 이렇게 직접 입력해서 들어갈 때에는, 서버라우트를 한번 타게 됩니다. 그러면 서버쪽에서 리액트앱으로 연결시켜줘야하죠. 실제 서버에서는, 우리가 설정한 라우트에 들어왔을때 리액트 앱이 보여지는 페이지를 보여주게 하거나, 혹은 API 등 사전 준비된 라우트를 제외한 모든 요청을 리액트 앱쪽으로 연결시켜주는 작업을 해야합니다. 그렇게 하지 않으면 서버측에서는 연결 할 라우트가 없어서 404 Not Found 페이지만 뜰 것입니다.

테스팅을 완료했다면 한번 Home 라우트의 exact 를 지워보세요.

두 컴포넌트가 같이 보여졌죠? exact 를 하지 않으면, /about 에도 / 가 있기 때문에, 매칭이 되어서 보여지는거랍니다. 확인을 하셨다면 다시 exact 를 적으세요.

라우트 파라미터 읽기

라우트의 경로에 특정 값을 넣는 방법을 알아보겠습니다. 방법은 두가지가 있는데요, params 를 사용하는 것 과, query 를 사용하는 것 입니다.

라우트로 설정한 컴포넌트는, 3가지의 props 를 전달받게 됩니다:

  • history 이 객체를 통해 push, replace 를 통해 다른 경로로 이동하거나 앞 뒤 페이지로 전환 할 수 있습니다.
  • location 이 객체는 현재 경로에 대한 정보를 지니고 있고 URL 쿼리 (/about?foo=bar 형식) 정보도 가지고있습니다.
  • match 이 객체에는 어떤 라우트에 매칭이 되었는지에 대한 정보가 있고 params (/about/:name 형식) 정보를 가지고있습니다.

URL 쿼리의 경우엔 컴포넌트 내에서 동적으로 사용 할 수 있고, params 의 경우엔 사용하기 전에 꼭 라우트에서 지정을 해주어야합니다.

params

그러면, 먼저 params 부터 사용을 해봅시다.

App 컴포넌트에서 다음과 같이 /about/:name 라우트를 추가하세요.

src/App.js

import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import { Home, About } from 'pages';

class App extends Component {
    render() {
        return (
            <div>
                <Route exact path="/" component={Home}/>
                <Route path="/about" component={About}/>
                <Route path="/about/:name" component={About}/>
            </div>
        );
    }
}

export default App;

URL 의 params 를 설정 할 때에는 :foo 의 형식으로 설정합니다. 이렇게 하면 foo 라는 params 가 생기는것이지요.

설정을 하셨다면, About 컴포넌트는 다음과 같이 수정해보세요.

src/pages/About.js

import React from 'react';

const About = ({match}) => {
    return (
        <div>
            <h2>About {match.params.name}</h2>
        </div>
    );
};

export default About;

우리가 name 이라는 params 를 만들었으니, 이 값은 match.params.name 을 통하여 확인 할 수 있습니다.

한번 브라우저에서 /about/foo 경로로 들어가보세요.

이런, About 컴포넌트가 중복됐군요.

어떻게 해결해야할까요? 네. exact 를 사용하면 되겠죠? 이를 해결하는 또 다른 방법이있습니다. 바로 Switch 컴포넌트를 사용하는건데요, 라우트들을 이 컴포넌트에 감싸면 매칭되는 첫번째 라우트만 보여주고 나머지는 보여주지 않습니다.

다음과 같이 Switch 를 불러온다음에 about 라우트 두개를 감싸주세요.

src/App.js

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

class App extends Component {
    render() {
        return (
            <div>
                <Route exact path="/" component={Home}/>
                <Switch>
                    <Route path="/about/:name" component={About}/>
                    <Route path="/about" component={About}/>
                </Switch>
            </div>
        );
    }
}

export default App;

주의 하실 점은, 먼저 비교 할 라우트를 위에 작성하셔야 한다는 점 입니다. 만약에 /about 을 /about/:name 보다 위에 넣어준다면, name 을 입력해주어도 나타나지 않을거에요.

아니면 이렇게도 할 수 있습니다!

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

class App extends Component {
    render() {
        return (
            <div>
                <Route exact path="/" component={Home}/>
                <Route path="/about/:name?" component={About} />
            </div>
        );
    }
}

뒤에 ? 가 들어가면 생략했을때도 매칭한다는 뜻 입니다.

URL 쿼리

리액트 라우터 v3 에서는 URL 쿼리를 해석해서 객체로 만들어주는 기능이 자체적으로 있었는데요, 쿼리를 파싱하는 방식은 여러가지가 있어서, 개발자들이 여러가지를 방식을 사용 할 수 있도록 이 기능을 더이상 내장하지 않습니다. 따라서 URL 쿼리를 해석하는것은 우리의 몫입니다.

쿼리를 해석하기 위해선, 라이브러리를 설치해주세요. 자체적으로 구현하는 방법도 있겠지만 라이브러리를 사용하는것이 훨씬 간편합니다.

$ yarn add query-string@5

브라우저에서 사용시에는 구버전의 자바스크립트 환경에서도 돌아 갈 수 있도록 @5 버전을 설치해주셔야 합니다.

그리고, About 의 코드를 다음과 같이 작성하세요.

src/pages/About.js

import React from 'react';
import queryString from 'query-string';

const About = ({location, match}) => {
    const query = queryString.parse(location.search);
    console.log(query);

    return (
        <div>
            <h2>About {match.params.name}</h2>
        </div>
    );
};

export default About;

그리고 나서 /about/foo?detail=true 경로로 들어가서 개발자콘솔을 확인해보세요.

detail 값이 객체에 생겼지요?

그러면, 이 값에 따라서 조건부 렌더링을 해보도록 하겠습니다.

src/pages/About.js

import React from 'react';
import queryString from 'query-string';

const About = ({location, match}) => {
    const query = queryString.parse(location.search);

    const detail = query.detail === 'true';

    return (
        <div>
            <h2>About {match.params.name}</h2>
            {detail && 'detail: blahblah'}
        </div>
    );
};

export default About;

이제 ?detail=true 가 주소 뒤에 붙어야만, 'detail: blahblah' 문자열이 나타나게 됩니다.

URL 쿼리를 만들 때 주의하실 점은, 받아오는 값들은 모두 문자열이라는 것 입니다. 따라서 비교를 해야 할 땐 boolean 을 불러오던 숫자를 불러오던, 문자열 형태로 비교를 하거나, 알맞는 형태로 변환을 시킨다음에 비교를 하세요.

results matching ""

    No results matching ""