본문 바로가기

Front/React

[React] 리액트 라우터 부가 기능

1. history

  • 라우트로 사용된 컴포넌트에 match, location과 함께 전달되는 props중 하나
  • 이 객체를 통해 컴포넌트 내에 구현하는 메서드에서 라우터 API를 호출할 수 있다.
  • 예) 특정 버튼을 눌렀을 때 뒤로 가거나, 로그인 후 화면을 전환하거나, 다른 페이지로 이탈하는 것을 방지해야할 때

 

[HistorySample.js]

import React, {Component} from 'react'

class HistorySample extends Component{
    // 뒤로가기
    handleGoBack = () => {
        this.props.history.goBack();
    };

    // 홈으로 이동
    handleGoHome = () => {
        this.props.history.push('/');
    };

    componentDidMount() {
        // 이것을 설정하고 나면 페이지에 변화가 생기려고 할 때마다 정말 나갈 것인지 질문함
        this.unblock = this.props.history.block('정말 떠나실 건가요?');
    }

    componentWillUnmount(){
        // 컴포넌트가 언마운트되면 질문을 멈춤
        if(this.unblock){
            this.unblock();
        }
    }

    render() {
        return (
            <div>
                <button onClick={this.handleGoBack}>뒤로</button>
                <button onClick={this.handleGoHome}>홈으로</button>
            </div>
        );
    }
}

export default HistorySample

 

[App.js]

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

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 = '/history'>History 예제</Link>
        </li>
      </ul>
      <hr />
      <Route path='/' component={Home} exact={true}/>
      <Route path={['/about', '/info']} component={About}/>
      <Route path='/profiles' component={Profiles}/>
      <Route path='/history' component={HistorySample} />
    </div>
  );
};

export default App

 

[결과]

 

2. withRouter

  • HoC(Higher-order Component)입니다.
  • 라우트로 사용된 컴포넌트가 아니어도 match, location, history객체에 접근할 수 있게 해줌

[WithRouterSample.js]

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)}
                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);

- withRouter를 사용할 때는 컴포넌트를 내보내 줄 때 함수로 감싸줍니다.

- JSON.stringify의 두번째 파라미터와 세번째 파라미터를 위와 같이 null, 2로 설정해주면 JSON에 들여쓰기가 적용된 상태로 문자열이 만들어짐

 

[Profile.js]

import React from 'react';
import {withRouter} from 'react-router-dom';
import WithRouterSample from "./WithRouterSample";

const data = {
    velopert: {
        name: '최수녕',
        description: '리액트를 좋아하는 개발자'
    },
    gildong: {
        name: '홍길동',
        description: '고전 소설 홍길동전의 주인공'
    }
};

const Profile = ({ match }) => {
    const {username} = match.params;
    const profile = data[username];
    if (!profile){
        return <div>존재하지 않는 사용자입니다.</div>
    }
    return (
        <div>
            <h3>
                {username}({profile.name})
            </h3>
            <p>{profile.description}</p>
            <WithRouterSample />
        </div>
    );
};

export default withRouter(Profile)

 

[결과]

 

 

3. Switch

  • 여러 Route를 감싸서 그중 일치하는 단 하나의 라우트만을 렌더링 시켜줌
  • 모든 규칙과 일치하지 않을 때 보여 줄 Not Found 페이지도 구현할 수 있다.

 

[App.js]

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

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 = '/history'>History 예제</Link>
        </li>
      </ul>
      <hr />
      <Switch>
        <Route path='/' component={Home} exact={true}/>
        <Route path={['/about', '/info']} component={About}/>
        <Route path='/profiles' component={Profiles}/>
        <Route path='/history' component={HistorySample} />
        <Route
          // path를 따로 정의하지 않으면 모든 상황에 렌더링됨
          render={({ location }) => (
            <div>
              <h2>이 페이지는 존재하지 않습니다:</h2>
              <p>{location.pathname}</p>
            </div>
          )}
          />
      </Switch>
    </div>
  );
};

export default App

 

[결과]

 

4. NavLink

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

[Profiles.js]

import React from 'react';
import { NavLink, Route } from "react-router-dom";
import Profile from './Profile';

const Profiles = () => {
    const activeStyle = {
        background: 'black',
        color: 'white'
    }
    return (
        <div>
            <h3>사용자 목록 : </h3>
            <ul>
                <li>
                    <NavLink activeStyle={activeStyle} to='/profiles/velopert'>
                        velopert
                    </NavLink>
                </li>
                <li>
                    <NavLink activeStyle={activeStyle} to='/profiles/gildong'>
                        gildong
                    </NavLink>
                </li>
            </ul>

            <Route
                path='/profiles'
                exact
                render={() => <div>사용자를 선택해 주세요</div>}
            />
            <Route path='/profiles/:username' component={Profile} />
        </div>
    );
};

export default Profiles;

 

[결과]

'Front > React' 카테고리의 다른 글

[React] Context API  (0) 2021.01.14
[React] 외부 API를 연동하여 뉴스 뷰어 만들기  (0) 2021.01.12
[React] 리액트 라우터 부가 기능  (0) 2021.01.09
[React] 서브 라우트  (0) 2021.01.09
[React] URL 파라미터와 쿼리  (0) 2021.01.09
React 배우기  (0) 2021.01.05