13.1 SPA란?

13.1.1 SPA의 단점

  • 앱의 규모가 커지면 자바스크립트 파일이 너무 커짐(실제로 방문하지 않을 수도 있는 페이지의 스크립트까지 불러오기 때문) => 코드 스플리팅을 통해 속도 개선
  • 자바스크립트를 실행하지 않는 일반 크롤러에서 페이지의 정보를 제대로 수집해 가지 못함 => 서버 사이드 렌더링을 통해 해결

13.2 프로젝트 준비 및 기본적인 사용법

13.2.1 프로젝트 생성 및 라이브러리 설치

yarn create react-app router-tutorial
cd router-tutorial
yarn add react-router-dom

13.2.2 프로젝트에 라우터 적용

import React from 'react';
import ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import {BrowserRouter} from 'react-router-dom';

ReactDOM.render(
    <BrowserRouter>
        <App/>
    </BrowserRouter>,
    document.getElementById('root')
);

serviceWorker.unregister();

13.2.3 페이지 만들기

13.2.4 Route 컴포넌트로 특정 주소에 컴포넌트 연결

import React from 'react';
import {Route} from 'react-router-dom';
import Home from "./Home";
import About from "./About";

const App = () => {
    return (
        <div>
            <Route path="/" component={Home} exact={true}/>
            <Route path="/about" component={About}/>
        </div>
    );
}

export default App;

13.2.4 Link 컴포넌트를 사용하여 다른 주소로 이동하기

<Link to="주소">내용</Link>

13.3 Route 하나에 여러 개의 path 설정하기

import React from 'react';
import {Route} from 'react-router-dom';
import Home from "./Home";
import About from "./About";

const App = () => {
    return (
        <div>
            <Route path="/" component={Home} exact={true}/>
            <Route path={['/about', '/info']} component={About}/>
        </div>
    );
}

export default App;

13.4 URL 파라미터와 쿼리

13.4.1 URL 파라미터

//router 설정
<Route path="/profile/:username" component={Profile}/>

//Link 설정
<Link to="/profile/test">test 프로필</Link>

//component 설정
import React from "react";

const Profile = ({match}) => {
    const {username} = match.param;
...
}

13.4.2 URL 쿼리

//쿼리 문자열을 객체로 변환하기 위한 qs 라이브러리 설치
yarn add qs

location 객체가 라우트로 사용된 컴포넌트에게 props로 전달됨
{
 "pathname" : "/about",
 "search" : "?detail=true",
 "hash" : ""
}

import React from "react";
import qs from 'qs';

const About = ({location}) => {
    const query = qs.parse(location.search, {
        ignoreQueryPrefix: true //문자열 맨 앞의 ?를 생략 
    });
    
    return (
    ...
    );
};

export default About;

13.5 서브 라우트

라우트 내부에 또 라우트를 정의하는 것
Route 컴포넌트에는 componet 대신 render라는 prop로 보여 주고 싶은 JSX를 넣어 줄 수 있음.
JSX에서 props를 설정할 때 값을 생략하면 자동으로 true로 설정됨. (ex> exact={true} 와 exact는 동일 표현)

<Route path="/profiles" exact render={()=><div>사용자를 선택해 주세요.</div>}/>

13.6 리액트 라우터 부가 기능

13.6.1 history

match, location과 함께 전달되는 props중 하나로,  이 객체를 통해 컴포넌트 내에 구현하는 메서드에서 라우터  API를 호출할 수 있음.

13.6.2 withRouter

라우트로 사용된 컴포넌트가 아니어도 match, location, history 객체를 접근할 수 있게 해 줌

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

const withRouterSample = ({location, match, history}) => {
    return (
        <div>
            <h4>location</h4>
			
            <textarea
                value={JSON.stringify(location, null, 2)}//2, 3번째 파라미터를 null, 2로 설정해주면 JSON에 들여쓰기가 적용된 상태로 문자열이 만들어짐
                rows={7}
                readOnly={true}/>
            <h4>match</h4>
            <textarea
                value={JSON.stringify(match, null, 2)}
                rows={7}
                readOnly={true}/>
            <button onClick={() => history.push('/')}>홈으로</button>
        </div>
    );
};

export default withRouter(withRouterSample);

13.6.3 Switch

Switch 컴포넌트는 여러 Router를 감싸서 그중 일치하는 단 하나의 라우트만을 렌더링 시켜 줌.  Swtich를 사용하면 모든 규칙과 일치하지 않을 때 보여 줄 Not Fount 페이지를 구현할 수 있음.

import React from 'react';
import {Route, Link, Switch} from 'react-router-dom';
import Home from "./Home";
import About from "./About";
import Profile from "./Profile";

const App = () => {
    return (
        <div>
            <ul>
                <li><Link to="/">홈</Link></li>
                <li><Link to="/about">소개</Link></li>
                <li><Link to="/profiles">프로필</Link></li>
                <li><Link to="/test">test</Link></li>
            </ul>
            <hr/>
            <Switch>
                <Route path="/" component={Home} exact={true}/>
                <Route path={['/about', '/info']} component={About}/>
                <Route path="/profile/:username" component={Profile}/>
                <Route render={({location}) => (
                    <div>
                        <h2>이 페이지는 존재하지 않습니다.</h2>
                        <p>{location.pathname}</p>
                    </div>
                )}>

                </Route>
            </Switch>
        </div>
    );
}

export default App;

13.6.4 NavLink

현재 경로와 Link에서 사용하는 경로가 일치하는 경우 특정 스타일 혹은 CSS 클래스를 적용할 수 있는 컴포넌트. NavLink에서 링크가 활성화되었을 때의 스타일을 적용할 때는  activeStyle값을, CSS 클래스를 적용할 때는 activeClassName 값을 prop로 넣어 주면 됨.

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

const Profile = ({match}) => {
    const activeStyle = {
        background: 'black',
        color: 'white'
    };
    return (
        <div>
            <h3>사용자 목록</h3>
            <ul>
                <li>
                    <NavLink activeStyle={activeStyle} to="/profiles/test1" active>
                        test1
                    </NavLink>
                </li>
                <li>
                    <NavLink activeStyle={activeStyle} to="/profiles/test2">
                        test2
                    </NavLink>
                </li>
            </ul>
        </div>
    );
}

export default Profile;

+ Recent posts