FRONT-END/REACTJS

react route로 SPA 개발

JINGMONG 2022. 2. 19. 22:17

리액트 라우터 v6 변경점

switch → routes 네이밍 변경

기존의 route 들을 구성하는 부모 요소를 switch 라는 네이밍으로 사용하였지만 v6에서는 route 복수개를 뜻하는 routes로 이름이 변경되었다.

StaticRouter의 import 위치 변경

import { StaticRouter } from 'react-router-dom/server';

exact 옵션 삭제

기존 / 라우트의 경우 React Router 의 디폴트 매칭 규칙으로 인해 앞부분만 일치해도 전부 매칭되기 때문에 정확히 라우트를 일치시키고자 exact 속성을 사용하였으나 v6부터 기본적으로 정확히 일치하도록 매칭 규칙이 변하여 exact 옵션을 더이상 하용하지 않는다. 만약 하위경로에 여러 라우팅을 매칭시키고 싶다면 URL 뒤에 *을 사용하여 일치시킬 수 있다.

route 에서 컴포넌트 렌더링

Route 컴포넌트의 render 속성을 사용하는 방식으로 사용하였지만 element 속성을 통해 바로 넣어줄 수 있도록 개선 되었다.

// v5 버전 사용 예시
<Route path='user' component={UserInfo} />
<Route
  path='user'
  render={routeProps => (
    <UserInfo routeProps={routeProps} isLogin={true} />
  )}
/>

// v6 버전 사용 예시
<Route path='user' element={<UserInfo />} />
<Route path='user' element={<UserInfo isLogin={true} />} />

중첩 라우팅

하나의 파일에 모든 경로를 지정하고 중첩 영역 렌더링 요소에는 Outlet 속성을 제공하여 간결하게 중첩된 라우트 구조를 사용하도록 개선 되었다.

중첩된 라우팅요소도 최상단에서 관리가 가능해 라우팅 요소를 한곳으로 모을수 있다.

useHistory 훅 → useNavigate

useHistory 네이밍을 useNavigate로 변경하였고 기존의 push, replace 등의 메소드로 동작하는 부분이 변경되었다.

const navigate = useNavigate();

navigate('/home');
navigate('/home', {replace: true});

<button onClick={() => navigate(-2)}>Go 2 pages back</button>
<button onClick={() => navigate(-1)}>Go back</button>
<button onClick={() => navigate(1)}>Go forward</button>
<button onClick={() => navigate(2)}>Go 2 pages forward</button>

리액트 라우터

$ yarn add react-router-dom

프로젝트에 리액트 라우터를 적용할 때는 src/index.js 파일에서 react-router-dom에 내장되어 있는 BrowserRouter라는 컴포넌트를 사용하여 감싸면 된다.

URL 연결

먼저 index.js를 BrowserRouter로 감싸준다.

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

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

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

페이지 만들기

import React from "react";

const Home = () => {
  return (
    <div>
      <h1>홈</h1>
      <p>홈, 그 페이지는 가장 먼저 보여지는 페이지.</p>
    </div>
  );
};

export default Home;
import React from 'react';

const About = () => {
  return (
    <div>
      <h1>소개</h1>
      <p>이 프로젝트는 리액트 라우터 기초를 실습해 보는 예제 프로젝트 입니다.</p>
    </div>
  );
};

export default About;

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

<Route path="주소규칙" element={<보여줄 컴포넌트 />} />
import { Route, Routes } from "react-router-dom";
import About from "./About";
import Home from "./Home";

const App = () => {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
    </Routes>
  );
};

export default App;

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

<Link to="주소">내용</Link>
import { Link, Route, Routes } from "react-router-dom";
import About from "./About";
import Home from "./Home";

const App = () => {
  return (
    <div>
      <ul>
        <li>
          <Link to="/">홈</Link>
        </li>
        <li>
          <Link to="/about">소개</Link>
        </li>
      </ul>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </div>
  );
};

export default App;

URL 파라미터와 쿼리

페이지 주소를 정의할 때 유동적인 값을 전달해야 할 때가 있다. 이를 파라미터와 쿼리로 나눌 수 있다.

ex) 파라미터 : /profile.velopert
ex) 쿼리 : /about?detail=ture

URL 파라미터

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

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

const Profile = () => {
  let params = useParams();
  const profile = data[params.username];

  if (!profile) {
    return <div>존재하지 않는 사용자입니다.</div>;
  } else {
    return (
      <div>
        <h3>{params.username}</h3>
        <p>{profile.description}</p>
      </div>
    );
  }
};

export default Profile;
import { Link, Route, Routes } from "react-router-dom";
import About from "./About";
import Home from "./Home";
import Profile from "./Profile";

const App = () => {
  return (
    <div>
      <ul>
        <li>
          <Link to="/">홈</Link>
        </li>
        <li>
          <Link to="/about">소개</Link>
        </li>
        <li>
          <Link to="/profile/velopert">velopert 프로필</Link>
        </li>
        <li>
          <Link to="/profile/gildong">gildong 프로필</Link>
        </li>
      </ul>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="profile">
          <Route path=":username" element={<Profile />} />
        </Route>
      </Routes>
    </div>
  );
};

export default App;

URL 쿼리

쿼리는 location 객체에 들어있는 search값에서 조회할 수 있다.

{
  "pathname": "/...",
  "search": "?a=b",
  "hash": ""
}

URL 쿼리는 ?a=b&c=d와 같이 문자열에 여러가지 값을 설정해 줄 수 있다. search 값에서 특정 값을 읽어 오기 위해서는 이 문자열을 객체 형태로 변환해 주어야 한다.
쿼리 문자열을 객체로 변환할 때는 qs라는 라이브러리를 사용한다.

$ yarn add qs
import React from "react";
import { useLocation } from "react-router-dom";
import qs from "qs";

const About = () => {
  const query = useLocation();

  const showDetail =
    qs.parse(query.search, {
      ignoreQueryPrefix: true,
    }).detail === "true";

  return (
    <div>
      <h1>소개</h1>
      <p>
        이 프로젝트는 리액트 라우터 기초를 실습해 보는 예제 프로젝트 입니다.
      </p>
      {showDetail && <p>detail 값을 true로 설정하셨군요!</p>}
    </div>
  );
};

export default About;

서브 라우트

서브 라우트는 라우트 내부에 또 라우트를 정의하는 것을 의미한다.

navigate

navigate는 특정 버튼을 눌렀을 때 뒤로 가거나, 로그인 후 화면을 전환하거나, 다른 페이지로 이탈하는 것을 방지할 때 활용한다.

'FRONT-END > REACTJS' 카테고리의 다른 글

Context API  (0) 2022.02.19
react 비동기 작업  (0) 2022.02.19
컴포넌트 스타일링  (0) 2022.02.19
Hooks  (0) 2022.01.03
라이프사이클 메서드  (0) 2021.12.28