함께 성장하는 프로독학러

1. Route 와 파라미터, 쿼리 본문

Programming/react router_v4

1. Route 와 파라미터, 쿼리

프로독학러 2018. 5. 18. 13:06

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


이번 포스팅에서는 리액트 라우터에 대해서 좀 더 자세히 알아보도록 하겠습니다.


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

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


0) URL 에서 path 와 qurey string 이란?


http://a.com/topic?id=1


위와 같은 url 이 있다고 생각해 봅시다.

대부분의 웹 어플리케이션의 url 은 위와 같은 형식으로 이루어 져 있습니다.

위의 url 에서 'http://' 은 프로토콜을 의미합니다.

프로토콜 뒤에 나오는 'a.com' 을 도메인 이라고 부르고,

도메인 다음에 나오는 / 이후의 'topic' 같은 녀석을 path 라고 부릅니다.

path 이후의 ? 다음에 나오는 'id=1' 같은 녀석은 query string 이라고 부릅니다.

웹 어플리케이션은 url 의 path 와 qurery string 을 이용하여 어떤 정보를 불러올지 결정합니다.



1) 기본 라우트 준비


먼저, 첫 번째 라우트인 Home 을 만들어 보도록 하겠습니다.

Home 라우트는 url 에 아무런 path 도 주어지지 않았을 때 기본적으로 보여주는 라우트 컴포넌트 입니다.


(src/pages/Home.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react';
 
const Home = () => {
    return (
        <div>
            <h2>
                홈
            </h2>
        </div>
    );
};
 
export default Home;
cs


Home 과 같은 형식으로 About.js 파일도 만들어 주도록 하겠습니다.

About.js 는 url 의 /about path(경로)로 들어왔을 때 보여줄 라우트 컴포넌트입니다.


(src/pages/About.js)

1
2
3
4
5
6
7
8
9
10
11
import React from 'react';
 
const About = () => {
    return (
        <div>
            <h2>About</h2>
        </div>
    );
};
 
export default About;
cs


이제 pages 디렉토리에 있는 라우터 컴포넌트들을 한 파일로 import 할 수 있도록 pages 디렉토리의 index 파일을 만들어 주도록 하겠습니다.


(src/pages/index.js)

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


2) 라우트 설정하기


위에서 만든 라우트 컴포넌트를 라우트에 맞춰 보여줄 수 있도록 App 컴포넌트를 작성해 봅시다.


(src/shared/App.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
cs


위 코드의 두 번째 줄에서 react-router-dom 패키지의 Route 컴포넌트를 불러왔습니다.

세 번째 줄에서는 pages 디렉토리에서 (index 를 통해) Home, About 라우트 컴포넌트를 불러왔습니다.


9-10 번째 줄에서 Route 컴포넌트를 사용해 라우트 설정을 해 주었습니다.

Route 컴포넌트의 path 속성은 url 의 path 를 의미하며, '해당 path 에 접속했을 때' 를 뜻합니다.

그리고 component 속성은 해당 path 에 접속했을 때 보여줄 컴포넌트를 지정하는 속성입니다.

즉, component 속성값에 해당하는 컴포넌트를 path 속성값의 path 로 접속했을 때 보여주도록 하는 Route 입니다.


* exact 속성은 말 그대로 정확한 path 경로를 의미합니다. exact 속성이 없다면, 두 라우트 모두 '/' 를 포함하고 있기 때문에 두 번째 라우트인 /about 경로에 접속했을 때 '홈' 이라는 글자가 보이게 됩니다. 이를 방지하기 위해 exact 속성을 사용합니다.


우리가 설정한 라우트가 제대로 작동하는지 확인해 봅시다.


npm start


프로젝트의 경로에서 npm start 를 통해 개발서버를 실행해 줍니다.



도메인 이후의 path 에 아무것도 입력하지 않은 경우(=/)에 Home 라우트 컴포넌트에서 입력한 글자 '홈' 이 잘 보이는 것을 알 수 있습니다.



url 의 path 에 /about 을 입력하면 우리가 설정한대로 라우트가 About 컴포넌트를 재대로 보여주고 있습니다.


만약 Home 라우트에서 exact 속성이 없다면 어떻게 되는지 한 번 살펴볼까요?



/about 경로에는 / 가 있기 때문에 Home 컴포넌트도 같이 보여지는 것을 알 수 있습니다.


3) 라우트 파라미터 읽기


라우트의 경로에 특정 값을 넣는 방법에 대해서 알아보도록 하겠습니다.

값을 넣는 방법은 두 가지가 있습니다. params 를 사용하는 방법과, query 를 사용하는 방법입니다.


먼저, 컴포넌트가 받는 props 가 어떤것이 있는지 알아볼 수 있는 크롬 확장기능인 'React Developer Tools' 를 설치합니다.



설치를 하고, 리액트로 이루어진 어플리케이션에서 개발자 도구(단축키 F12)에 들어가면 React 탭이 활성화 되어있는 것을 알 수 있습니다.


React 탭으로 들어가 봅시다.



검색창에 about 을 입력하여 About 컴포넌트를 검색했습니다.


About 컴포넌트를 클릭하면, 오른쪽에 해당 컴포넌트가 전달받는 Props 들이 나열되어 있는 것을 알 수 있습니다.


라우트로 설정한 컴포넌트는 기본적으로 3가지의 props 를 전달받습니다. (모두 객체입니다)


  • history : history 객체의 push, replace 를 통해 다른 경로로 이동시키거나 앞 뒤 페이지로 전환시킬 수 있습니다.
  • location : location 객체는 현재 경로에 대한 정보를 지니고 있습니다. (location.pathname 속성값은 url 의 path 를 가르키고, location.search 속성값은 쿼리스트링의 정보를 가르킵니다)
  • match : match 객체는 해당 컴포넌트가 어떤 라우트에 매치되어 있는지에 대한 정보가 있습니다. 또한 파라메터 정보를 params 속성으로 지니고 있습니다.


* url 에서 query 의 경우에는 컴포넌트 내에서 동적으로 사용할 수 있고, params 의 경우에는 라우트 단에서 먼저 지정을 해주어야 합니다.


params


먼저 params 를 통해 라우트에 특정 값을 넣는 방법에 대해서 알아보도록 하겠습니다.


App 컴포넌트에서 Route 를 하나 더 추가해 보도록 하겠습니다.


(src/shared/App.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;
cs


위 코드의 11번째 줄에서 /about/:name 경로의 라우트를 추가했습니다.

위와 같이 url 에서 파라메터를 사용할 때는 :PARAM_NAME 처럼 : 뒤에 파라미터의 이름을 지정해 줍니다.

위의 코드에서는 name 이라는 파라메터가 생긴 것입니다.


name 파라메터를 표시하기 위해 About 컴포넌트를 수정해 봅시다.


(src/pages/About.js)

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


코드의 세 번째 줄에서 함수형 컴포넌트에 Props 를 인자로 전달했습니다. (Dumb 컴포넌트)


그리고 6번째 줄에서 Props 로 전달받은 match 객체의 params.name 을 이용하여 name 파라메터로 들어온 값을 h2 태그 안에 표시하도록 했습니다.


우리의 어플리케이션에서 /about/pro-self-studier 경로로 들어가 봅시다.



위처럼 About 컴포넌트가 두 개 렌더링 된 것이 보일 것입니다.


이는 /about 경로가 중복됐기 때문입니다. (/about 라우트와 /about/:name 라우트에 /about 경로가 중복되어 있다)

이는 위에서 언급한 바와 같이 exact 속성을 이용하면 해결 가능합니다.


하지만 이번에는 exact 속성이 아닌 Switch 컴포넌트를 통해 이 문제를 해결해 보도록 하겠습니다.

Switch 컴포넌트는 react-router-dom 패키지에 내장되어 있는 컴포넌트로, 자바스크립트의 switch 문을 사용하는 것과 비슷합니다.

* 자바스크립트의 switch 조건문에 익숙하지 않으신 분들은 아래의 링크를 참조해 주세요.

<자바스크립트의 switch 조건문>


(src/shared/App.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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;
cs


코드의 두 번째 줄에서 Switch 컴포넌트를 불러왔습니다.

그리고 10-13 번째 줄에서 Switch 컴포넌트를 사용했습니다.


Switch 컴포넌트를 사용하는 방법은 위와 같이 검사를 할 대상 라우트를 Switch 컴포넌트 안에 위치 시키는 것입니다.

Switch 컴포넌트는 자신의 자식으로 들어온 라우트들을 위에서 부터 아래로 하나씩 검사하며, 해당 경로에 해당하는 라우트를 실행시킵니다.

실행이 되는 순간, Switch 컴포넌트는 자식들을 검사하는 작업을 중지합니다.

따라서, /about 라우트 보다 /about/:name 라우트가 상단에 위치해야 합니다.

* 순서가 바뀌게 되면 name 을 입력해 줘도 /about 라우트가 작동하기 때문에 params 의 값이 표시 되지 않습니다.


URL query


params 를 이용해 라우트에 값을 지정한 것에 이어 URL query 를 이용하는 방법에 대해서 알아보도록 하겠습니다.


url 에 들어온 쿼리스트링은 말그대로 string 형태의 데이터 입니다.

이를 객체로 변환하여 사용하려면 쿼리를 해석(파싱) 해 주어야 합니다.

쿼리를 파싱하는 방법에는 여러가지가 있겠지만, 우리는 query-string 이라는 라이브러리를 사용해 보도록 하겠습니다.


npm install --save query-string


프로젝트의 루트 경로에서 위의 명령어를 입력하여 query-string 라이브러리를 추가해 줍시다.


그리고 About 컴포넌트를 다음과 같이 수정해 줍니다.


(src/pages/About.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
cs


코드의 두 번째 줄에서 query-string 을 불러왔습니다.

query-string을 사용하는 방법은 queryString 객체의 parse 메소드를 이용하면 됩니다.

이를 통해 쿼리스트링을 객체 형태로 파싱할 수 있습니다.

* url 에 입력한 쿼리스트링의 값은 해당 컴포넌트가 location.search Props 로 전달 받습니다.


어플레케이션에 /about/pro-self-studier?query=true 경로로 접속해 봅시다.



콘솔창을 열어 확인해 보면, 쿼리스트링으로 입력한 값이 객체형태로 잘 파싱되어 출력된 것을 알 수 있습니다.


이를 활용하여 조건부 렌더링을 해 보도록 하겠습니다.


(src/pages/About.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;
cs


위 코드의 7번째 줄에서 detail 상수를 정의 했는데, 상수의 값으로 파싱된 쿼리의 detail 값이 true 라는 것을 할당했습니다.


그리고 12 번째 줄에서 AND 연산자를 사용해 detail 일 때(쿼리스트링으로 detail 값이 true 로 전달 됐을 때) 'detail: blahblah' 가 표시되도록 했습니다.

* ANd 연산자는 && 앞의 값이 true 일때 && 뒤의 값을 반환하며, 조건이 false 라면 아무값도 반환하지 않는 연산자 입니다.


/about/pro-self-studier?detail=true 경로로 접속하면, 'detail: blahblah' 가 잘 뜨는 것을 확인할 수 있습니다.



* url 쿼리를 통해 받아오는 값들은 모두 문자열입니다.


여기까지...


리액트 라우터를 이용해 url 에 따라 원하는 컴포넌트를 렌더링 하는 라우팅과 url 안에서 파라메터를 사용하는 법, url 의 쿼리스트링을 파싱해서 사용하는 방법에 대해서 알아보았습니다.


라우트로 설정한 컴포넌트들은 3가지의 Props 를 기본적으로 전달 받는다는 것과, params 를 사용하려면 match.params.PARAM_NAME 프롭스를 이용하는 것과, 쿼리를 이용하려면 location.search 프롭스를 이용한다는 것을 기억하고 있으면 좋을 것 같습니다.


그럼 다음 포스팅에서는 어플리케이션 안에서 다른 라우트로 이동하는 방법들에 대해서 알아보도록 하겠습니다.


감사합니다.


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

https://velopert.com/3417


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

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

3. 라우트 내부의 라우트  (1) 2018.05.21
2. 라우트 이동  (0) 2018.05.21
0. 리액트 라우터 소개, 설치 및 설정  (0) 2018.05.17
Comments