6일차(5.1~5.5)

리액트 라우터

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

1. 라이브러리 설치

yarn add react-router-dom

2. 프로젝트에 라우터 적용

// src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom'; // * BrowserRouter 불러오기
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

// * App 을 BrowserRouter 로 감싸기
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

serviceWorker.unregister();

3. 라우트로 사용할 페이지 컴포넌트 생성

4. Route: 특정 주소에 컴포넌트 연결하기

사용 방식

<Route path="주소규칙" component={보여주고싶은 컴포넌트}>
// src/App.js

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

const App = () => {
  return (
    <div>
      // exact - 경로가 완벽히 똑같을때만 컴포넌트를 보여주게 된다
      <Route path="/" exact component={Home} /> // 설정한 경로 일때 컴포넌트를 보여주게 된다
      <Route path="/about" component={About} />
    </div>
  );
};

export default App;

5. Link: 누르면 다른 주소로 이동시키기

Link 컴포넌트

  • 클릭하면 다른 주소로 이동시키는 컴포넌트
  • a태그와 달리 브라우저의 주소만 바꿀 뿐 페이지를 새로 불러오지는 않는다.
import React from 'react';
import { Route, Link } from 'react-router-dom';
import About from './About'; 
import Home from './Home';

const App = () => {
  return (
    <div>
      <ul>
        <li>
          <Link to="/"></Link> // 이동할 url을 to속성에 넣어준다
        </li>
        <li>
          <Link to="/about">소개</Link>
        </li>
      </ul>
      <hr />
      <Route path="/" exact={true} component={Home} />
      <Route path="/about" component={About} />
    </div>
  );
};

export default App;

02. 파라미터와 쿼리

페이지 주소를 정의 시 유동적인 값을 전달해야 할 때 파라미터 또는 쿼리를 사용한다

파라미터: /profiles/velopert // **특정 id**나 **이름**을 가지고 조회할 때 사용
쿼리: /about?details=true   // **키워드**를 검색하거나, **요청할 때 필요한 옵션**을 전달 할 때 사용

현재 주소의 파라미터 받아오기

Route컴포넌트에서 path속성에 경로를 지정해줄 때 /profiles/:parameter의 형식으로 작성해주면

Link컴포넌트에서 to속성에 이동할 경로를 설정할 때 paramter부분에 값을 유동적으로 넣을 수 있다

컴포넌트에서 props으로 match를 받고, match.params를 사용해서 현재의 주소에서 파라미터를 받아올 수 있다


03.서브라우트

  • 라우트 내부의 라우트를 만드는것을 의미
  • 컴포넌트를 만들어서 그 안에 또 Route컴포넌트를 렌더링하는 것
  • 특정 라우트 내에 탭 같은 것을 만들게 된다면, 단순히 state 로 관리하는 것 보다 서브 라우트로 관리하는 것을 권장
// src/Profiles.js

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

const Profiles = () => {
  return (
    <div>
      <h3>유저 목록:</h3>
      <ul>
        <li>
          <Link to="/profiles/velopert">velopert</Link>
        </li>
        <li>
          <Link to="/profiles/gildong">gildong</Link>
        </li>
      </ul>
			<Route path="/" exact={true} component={Home} />
      <Route path="/about" component={About} />
      <Route path="/profiles" component={Profiles} />
    </div>
  );
};

export default Profiles;
import React from 'react';
import { Link, Route } from 'react-router-dom';
import Profile from './Profile';

const Profiles = () => {
  return (
    <div>
      <h3>유저 목록:</h3>
      <ul>
        <li>
          <Link to="/profiles/velopert">velopert</Link>
        </li>
        <li>
          <Link to="/profiles/gildong">gildong</Link>
        </li>
      </ul>

// component속성 대신 render속성 사용 시 JSX 자체를 렌더링 할 수 있어서 상위 영역에서 
// props나 기타 값들을 필요하면 전달해 줄 수 있다
      <Route
        path="/profiles"
        exact
        render={() => <div>유저를 선택해주세요.</div>}
      />
      <Route path="/profiles/:username" component={Profile} />
    </div>
  );
};

export default Profiles;

Profiles컴포넌트가 그대로 남아있는 상태에서 Profile컴포넌트를 렌더링할 수 있다


04. 리액트 라우터 부가기능

history 객체

  • 라우트로 사용된 컴포넌트에게 match, location과 함께 전달되는 props 중 하나
  • 컴포넌트 내에 구현하는 메소드에서 라우터에 직접 접근 할 수 있다
  • 뒤로가기, 특정 경로로 이동, 이탈 방지 등
import React, { useEffect } from 'react';

function HistorySample({ history }) { // props에서 받아온다
  const goBack = () => {
    history.goBack();
  };

  const goHome = () => {
    history.push('/');
  };

  // 메시지박스를 통하여 이탈 막기
  useEffect(() => {
    console.log(history);
    const unblock = history.block('정말 떠나실건가요?');
    return () => { // 컴포넌트가 사라지기 직전에 실행
      unblock();
    };
  }, [history]); // 경로가 바뀔 때마다 실행

  return (
    <div>
      // 조건부로 다른 곳으로 이동 가능
      <button onClick={goBack}>뒤로가기</button>
      <button onClick={goHome}>홈으로</button>
    </div>
  );
}

export default HistorySample;

withRouter HoC

  • 라우트 컴포넌트가 아닌 곳에서 match / location / history 를 사용해야 할 때 쓰인다
  • 자신의 부모 컴포넌트 기준의 match 값이 전달
import React from 'react';
import { withRouter } from 'react-router-dom'; // import 후
const WithRouterSample = ({ location, match, history }) => { // props으로 받아서 사용
  return (
    <div>
      <h4>location</h4>
      <textarea value={JSON.stringify(location, null, 2)} readOnly />
      <h4>match</h4>
      <textarea value={JSON.stringify(match, null, 2)} readOnly />
      <button onClick={() => history.push('/')}>홈으로</button>
    </div>
  );
};

export default withRouter(WithRouterSample);

Switch

  • 여러 Route 들을 감싸서 그 중 규칙이 일치하는 라우트 단 하나만을 렌더링시켜준다
  • 아무것도 일치하지 않았을때 보여줄 Not Found 페이지를 구현 할 수도 있다
import { Switch, Route, Link } from 'react-router-dom';

<Switch>
        <Route path="/" exact={true} component={Home} />
        <Route path="/about" 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>

NavLink

  • 현재 경로와 Link 에서 사용하는 경로가 일치하는 경우 경로 이동 + 특정 스타일 혹은 클래스를 적용 할 수 있는 컴포넌트

05. useReactRouter Hook 사용하기

  • 라우트로 사용되고 있지 않은 컴포넌트에서 라우트 관련 props인 matchhistorylocation 을 조회할 수 있게 해주는 Hook
  • withRouter 를 사용하는 대신에 Hook 을 사용해서 구현을 할 수 있다
  • withRouter 가 너무 불편하다고 느낄 경우에만 사용하시는 것을 권장

출처 https://react.vlpt.us/

좋은 웹페이지 즐겨찾기