[React] react router V6

최현석·2022년 1월 21일
0

리액트

목록 보기
4/5

벨로퍼트님 리액트 라우터 v6 튜토리얼 을 읽고 재 정리하고, 내용을 추가한 글입니다.

1. 라우팅이란?

웹 어플리케이션에서 라우팅이라는 개념은 사용자가 요청한 URL에 따라 알맞는 페이지를 보여주는 것을 의미한다.

웹 어플리케이션을 만들 때 프로젝트를 하나의 페이지 혹은 여러 페이지로도 구성할 수 있다.

단일 페이지 말고, 여러 페이지로 구성된 웹 프로젝트를 구축할 때 두 가지 선택지가 있다.

  • 리액트 라우터 (React Router) : 가장 오래되고, 가장 많이 사용되는 이 라이브러리는 컴포넌트 기반으로 라우팅 시스템을 설정할 수 있다.

  • Next.js : Next.js 는 리액트 프로젝트의 프레임워크다. 이 프레임워크는 create react app 처럼 리액트 프로젝트를 설정하는 기능, 라우팅 시스템, 최적화, 다국어 시스템 지원, 서버 사이드 렌더링 등 다양한 기능들을 제공한다. 이 프레임워크의 라우팅 시스템은 파일 경로를 기반으로 작동한다. 리액트 라우터의 대안으로서 많이 사용된다.

라우팅 관련 기능은 리액트 라이브러리에서 공식 지원되는 것이 아니라, 서드 파티로서 제공되기 때문에 이외에도 react-location, rakkas 등의 프로젝트들이 존재한다.

그중에 가장 인기 있는 리액트 라우터를 사용하면 손쉽게 싱글 페이지 애플리케이션을 만들 수 있다.

2. 싱글 페이지 애플리케이션

싱글 페이지 애플리케이션이란, 한 개의 페이지로 이루어진 애플리케이션이라는 의미다.

싱글 페이지 애플리케이션이란 개념이 생기기 전에 사용되던 멀티 페이지 애플리케이션이 어떻게 작동하는지 먼저 살펴 보자면,

사용자가 다른 페이지로 이동할 때마다 새로운 html 을 받아오고, 페이지를 로딩할 때마다 서버에서 CSS, JS, 이미지 파일 등의 리소스를 전달 받아 브라우저 화면에 보여주었다. 각 페이지마다 다른 html 파일을 만들어서 제공하거나, 데이터에 따라 유동적인 html을 생성해주는 템플릿 엔진을 사용하기도 했다.

사용자의 인터랙션이 별로 없는 정적인 페이지들은 기존 방식이 적합하지만, 사용자 인터랙션이 많고 다양한 정보를 제공하는 모던 웹 애플리케이션은 이 방식이 적합하지 않았다.

새로운 페이지를 보여줄 때마다 서버 측에서 모든 준비를 한다면 그만큼 서버의 자원을 사용하고, 트래픽도 더 많이 나오기 때문이다.

그래서 리액트 같은 라이브러리를 사용해서 뷰 렌더링을 사용자의 브라우저가 담당하도록 하고, 우선 웹 애플리케이션을 브라우저에 불러와서 실행시킨 후에 사용자와의 인터랙션이 발생하면 필요한 부분만 자바스크립트를 사용하여 업데이트를 하는 방식을 사용하게 됐다.

만약 새로운 데이터가 필요하다면 서버 API를 호출하여 필요한 데이터만 새로 불어와 애플리케이션에서 사용할 수 있게 됐다.

이렇게 html을 한 번만 받아와서 웹 애플리케이션을 실행시킨 후에 그 이후에는 필요한 데이터만 받아와서 화면에 업데이트 해주는 것이 싱글 페이지 애플리케이션이다.

싱글페이지 애플리케이션은 기술적으로 한 페이지만 존재하는 것이지만, 사용자가 경험하기에는 여러 페이지가 존재하는 것 처럼 느낄 수 있다.

리액트 라우터와 같은 라우팅 시스템은 사용자의 브라우저 주소창의 경로에 따라 알맞는 페이지를 보여주는데, 이후 링크를 눌러서 다른 페이지로 이동하게 될 때 서버에 다른 페이지의 html 을 새로 요청하는 것이 아니라, 브라우저의 History API를 사용하여 브라우저의 주소창의 값만 변경하고, 기존 페이지에 띄웠던 웹 애플리케이션을 그대로 유지하면서 라우팅 설정에 따라 또 다른 페이지를 보여주게 된다.

3. 리액트 라우터 적용 및 기본 사용법

실습은 다음과 같이 진행된다.

  1. 프로잭트 생성 및 라이브러리 설치.
  2. 페이지를 만들고 이동해보기.
  3. URL 파라미터와 쿼리스트링 사용해보기.
  4. 중첩된 라우트 구현하기.
  5. 리액트 라우터의 부가기능 사용해보기.

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

우선 리액트 라우터를 적용할 리액트 프로젝트를 새로 생성한다.

$ yarn create react-app router-tutorial

그리고 해당 프로젝트 디렉토리로 이동하여 리액트 라우터 라이브러리를 설치해준다.

$ cd router-tutorial
$ yarn add react-router-dom

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

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

이 BrowserRouter 컴포넌트는 웹 애플리케이션에 HTML5의 History API를 사용하여 페이지를 새로 불러오지 않고도 주소를 변경하고 현재 주소의 경로에 관련된 정보를 리액트 컴포넌트에서 사용할 수 있도록 해준다.

src/index.js

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

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

리액트 리덕스 - 덩크 사용을 위해 index.js 에서 customHistorty 를 바인딩 했었는데,
리액트 라우터 v6로 오면서 해당 부분사용이 불가능 해졌다.

해당 부분 관련해서는 찾아보고 후술 하도록 하겠다.

// const customHistory = createBrowserHistory();

const store = createStore(
    rootReducer,
    composeWithDevTools(
        applyMiddleware(
            ReduxThunk,
            // .withExtraArgument({
            //     history: customHistory,
            // }),
            // logger,
        ),
    ),
);

ReactDOM.render(
    <React.StrictMode>
        // <Router histrory={customHistrory}/> -> <BrowserRouter /> 대체
            <Provider store={store}>
                <App />
            </Provider>
        // <Router histrory={customHistrory}/> -> <BrowserRouter /> 대체
    </React.StrictMode>,
    document.getElementById('root'),
);

3.3. 페이지 컴포넌트 만들기

리액트 라우터를 통해 여러 페이지로 구성된 웹 애플리케이션을 만들기 위하여 각 페이지에서 사용할 컴포넌트를 만들 차례다.
사용자가 웹 사이트에 들어오게 됐을 때 가장 먼저 보여지게 될 Home 페이지 컴포넌트와 웹 사이트를 소개하는 About 페이지 컴포넌트를 만들어 보자.

src 디렉터리에 pages 경로를 만들고, 그 안에 다음 파일들을 생성한다.

src/pages/Home.js

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

export default Home;

src/pages/About.js

const About = () => {
  return (
    <div>
      <h1>소개</h1>
      <p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
    </div>
  );
};

export default About;

이 컴포넌트들을 꼭 pages 경로에 넣을 필요는 없다. 구분을 위해 임의로 넣어준 것일 뿐이다.

3.4. Route 컴포넌트로 특정 경로에 원하는 컴포넌트 보여주기

사용자의 브라우저 주소 경로에 따라 우리가 원하는 컴포넌트를 보여주기 위해서 Route 라는 컴포넌트를 통해 라우트 설정을 해주어야 한다.

Route 컴포넌트는 다음과 같이 사용한다.

<Route path="주소규칙" element={보여줄 컴포넌트 JSX} />

그리고, Route 컴포넌트는 Routes 컴포넌트 내부에서 사용되어야 한다.

App 컴포넌트를 다음과 같이 Route 컴포넌트를 사용해 라우트 설정을 해보자.

src/App.js

import { Route, Routes } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';

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

export default App;

이제 yarn start 를 터미널에 입력해 개발 서버를 시작하면, 홈 컴포넌트가 나오게 된다.

이번에는 Link 컴포넌트를 사용하여 다른 페이지로 이동하는 링크를 보여주는 방법을 알아보자.

웹 페이지에서는 원래 링크를 보여줄 때 a 태그를 사용하는데, 리액트 라우터를 사용하는 프로젝트에서 a 태그를 바로 사용하면 안된다.

a 태그를 클릭해 페이지를 이동하게 되면, 브라우저에서는 페이지를 새로 불러오기 때문이다.

Link 컴포넌트 역시 a 태그를 사용하긴 하지만, 페이지를 새로 불러오는 것을 막고, History API를 통해 브라우저 주소의 경로만 바꾸는 기능이 내장되어 있다.

Link 컴포넌트는 다음과 같이 사용한다.

<Link to="경로">링크 이름</Link>

Home 페이지에서 About 페이지로 이동할 수 있도록 Link 컴포넌트를 Home 페이지 컴포넌트에서 사용해보자.

src/pages/Home.js

import { Link } from 'react-router-dom';

const Home = () => {
  return (
    <div>
      <h1></h1>
      <p>가장 먼저 보여지는 페이지.</p>
      <Link to="/about">소개 about</Link>
    </div>
  );
};
export default Home;

이제, 브라우저에서 우리가 방금 만든 소개 링크를 눌러 About 페이지로 이동할 수 있다.

3.6. to="" || path="" 주소 이동

문자열로 "/이동할 주소" 를 입력하게 되면, 절대 경로로서 "/이동할 주소" 주소로 이동하고.
"이동할 주소" 를 입력하게 되면, 상대 경로로서 "/현재주소/이동할주소/" 주소로 이동하게 된다.

4. URL 파라미터와 쿼리스트링

페이지 주소를 정의할 때 유동적인 값을 사용해야 할 경우가 있다.

  • URL 파라미터 예시 : /profile/jazzyfact
  • 쿼리스트링 예시 : /aticles?page=1&keyword=react

URL 파라미터는 주소의 경로에 유동적인 값을 넣는 형태고,
쿼리 스트링은 주소의 뒷부분 ? 문자열 이후에 key=value 로 값을 정의하며 & 로 구분하여 사용하는 형태다.

주로 URL 파라미터는 ID 또는 이름을 사용하여 특정 데이터를 조회할 때 사용하고,
쿼리 스트링은 키워드 검색, 페이지네이션, 정렬 방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용한다.

4.1. URL 파라미터

우선 URL 파라미터를 사용하는 방법을 알아보자.

이를 사용하기 위해 새로운 페이지 컴포넌트를 만들어 보자.

Profile 컴포넌트를 pages 경로에 다음과 같이 작성하자.

src/pages/Profile.js

import { useParams } from 'react-router-dom';

const data = {
 hyeonseok: {
   name: '최현석',
   description: '라우터 V6 실습중',
 },
 dongju: {
   name: '윤동주',
   description: '윤동주 시인',
 },
};

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

 return (
   <div>
     <h1>사용자 프로필</h1>
     {profile ? (
       <div>
         <h2>{profile.name}</h2>
         <p>{profile.description}</p>
       </div>
     ) : (
       <p>존재하지 않는 프로필 입니다.</p>
     )}
   </div>
 );
};

export default Profile;

URL 파라미터는 useParams 라는 Hook을 사용하여 객체 형태로 조회할 수 있다. URL파라미터의 이름은 라우트 설정할 때 Route 컴포넌트의 path props를 통하여 설정한다.

위 코드에서는 data 객체에 예시 프로필 정보들을 key-value 형태로 담아두었다.

그리고 Profile 컴포넌트에서는 username URL 파라미터를 통하여 프로필을 조회한 뒤에 프로필이 존재하지 않으면 "존재하지 않는 프로필입니다" 라는 문구를 보여주고 존재한다면 프로필 정보를 보여주도록 로직을 작성했다.

컴포넌트를 다 작성했으면 App 컴포넌트 파일을 열어서 새로운 라우트를 다음과 같이 설정해주자.

src/App.js

import { Route, Routes } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import Profile from './pages/Profile';

function App() {
 return (
   <Routes>
     <Route path="/" element={<Home />} />
     <Route path="/about" element={<About />} />
     <Route path="/profiles/:username" element={<Profile />} />
   </Routes>
 );
}

export default App;

URL 파라미터는 /profiles/:username 과 같이 경로에 : 를 사용하여 설정한다.

만약 URL 파라미터가 여러개인 경우엔 /profiles/:username:field 와 같은 형태로 설정할 수 있다.

이제, Profile 페이지로 이동 할 수 있도록 Home 페이지에 Link를 더 만들어보자. 링크가 여러 개 이기 때문에, ul 태그를 사용하여 리스트 형태로 보여주겠다.

src/pages/Home.js

import { Link } from 'react-router-dom';

const Home = () => {
  return (
    <div>
      <h1></h1>
      <p>가장 먼저 보여지는 페이지.</p>
      <ul>
        <li>
          <Link to="/about">소개 about</Link>
        </li>
        <li>
          <Link to="/profiles/hyeonseok">hyeonseok의 프로필</Link>
        </li>
        <li>
          <Link to="/profiles/dongju">dongju 의 프로필</Link>
        </li>
        <li>
          <Link to="/profiles/none">존재하지 않는 프로필</Link>
        </li>
      </ul>
    </div>
  );
};
export default Home;

4.2. 쿼리스트링

profile
노력과 성장을 기록합니다.

0개의 댓글