프론트엔드/React

[33] 리액트 라우터 추가 정리

반신욕좋아하는J 2022. 12. 19. 12:33
반응형

1. 라우팅이란 ?

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

여기서 여러페이지로 구성된 웹페이지에서 페이지별로 컴포넌트를 분리해가며 프로젝트를 관리하기위해 필요한것이 라우팅 시스템이다.

우리는 React-Router 를 사용해서 예제를 해보자

2. 싱글 페이지 어플리케이션이란?

말그대로 한개의 페이지로 이루어진 어플리케이션 이다.

기술적으로는 한페이지만 존재하는것이지만, 사용자는 여러 페이지가 존재하는것처럼 느낀다.

React-Router 는 링크를눌르면 브라우저에 History API 를 사용해 주소창 값만 변경하고
기존 페이지의 웹 어플리케이션은 유지 하면서 라우팅설정에따른 다른 페이지를 보여주는 방식이다.

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

3.1 프로젝트 생성

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

프로젝트 생성 → 디렉토리 이동 → 라이브러리 설치

3.2 라우터 적용

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

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

src/index.js 에 react-router-domBrowserRouter 로 감싸주면 끝

3.3 페이지 컴포넌트 생성

여러가지 페이지를 구성하기위해 페이지에 사용할 컴포넌트를 생성해보자

홈화면을 보여줄 Home 과 소개글을 보여줄 About 을 생성한다.

**Home.js**

const Home = () => {
  return (
    <div>
      <h1>홈</h1>
      <p>홈화면을 보여줌</p>
    </div>
  );
};

export default Home;

About.js

const About = () => {
  return (
    <div>
      <h1>소개</h1>
      <p>소개글을 보여줌</p>
    </div>
  );
};

export default About;

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

Route 컴포넌트의 규칙

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

Route 컴포넌트는 Routes 컴포넌트 내부에 사용되야됨

**App.js**

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

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

export default App;

3.5 Link 컴포넌트를 사용해 다른페이지로 이동하는 링크 보여주기

a 태그는 클릭하면 브라우저에서 페이지를 새로 불러오기때문에 리액트 라우터를 사용하는 프로젝트에서는 a태그 를 바로 사용하면 안된다.

Link 도 a 태그를 사용하지만 , 페이지를 새로불러오지않고 History API 를 통해 브라우저 주소의 경로만 바꾸는 기능이 내장되있다.

Link 컴포넌트 사용방법

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

Home.jsLink 컴포넌트 를 사용해보자

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

const Home = () => {
  return (
    <div>
      <h1>홈</h1>
      <p>홈화면을 보여줌</p>
      <Link to="/about">소개</Link>
    </div>
  );
};

export default Home;

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

페이지주소에 가끔 유동적인 값을 사용해야될때있다.

URL 는 주소의 경로에 유동적인 값을 넣는 형태 ,주로 id또는 이름을 사용해서 특정데이터를 조회할때 사용함

URL → /profile/jaehyun2yo

쿼리스트링 은 주소뒷부분에 ? 문자열이후에 key=value 를 정의하며 & 로 구분한다. 키워드검색, 페이지네이션 , 정렬방식등 데이터 조회에 필요한 옵션을 전달할때 사용한다.

쿼리스트링 → /articles?**page=1&keyword=react

4.1 URL 파라미터

새로운 profile 컴포넌트를 생성한다.

**Profile.js**

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

const data = {
  jaehyun2yo: {
    name: '김재현',
    description: '불속성 취준생 ',
  },
  person: {
    name: '누구게?',
    description: '?!??!?!?',
  },
};

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

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

export default Profile;

useParams 라는 Hook을 사용해 객체형태로 조회할수있다.

URL파라미터의 이름은 라우트설정시 Route 컴포넌트의 path props를 통해 설정한다.

**App.js**

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

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

export default App;

path 경로에 : 를 사용해 설정한다. 여러개인경우는 /profiles/:username/:field 식으로 설정할수있따.

이제 Home 페이지에 Link 컴포넌트를 더 생성해보자

**Home.js**

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

const Home = () => {
  return (
    <div>
      <h1>홈</h1>
      <p>홈화면을 보여줌</p>
      <ul>
        <li>
          <Link to="/about">소개 </Link>
        </li>
        <li>
          <Link to="/profiles/jaehyun2yo">jaehyun2yo 의 프로필</Link>
        </li>
        <li>
          <Link to="/profiles/person">person 의 프로필</Link>
        </li>
        <li>
          <Link to="/profiles/void">그런사람 없습니다.</Link>
        </li>
      </ul>
    </div>
  );
};

export default Home;

4.2 쿼리스트링

쿼리스트링은 별도의 Route 설정이 없다.

About.js

**import { useLocation } from 'react-router-dom';**

const About = () => {
  **const location = useLocation();**

  return (
    <div>
      <h1>소개</h1>
      <p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
      **<p>쿼리스트링: {location.search}</p>**
    </div>
  );
};

export default About;

useLocation 이라는 Hook을 사용한다. location객체를 반환하며 ,

이객체는 사용자가 보고있는 페이지의 정보를 갖고있다.

  • pathname: 현재 주소의 경로 (쿼리스트링 제외)
  • search: 맨 앞의 ? 문자 포함한 쿼리스트링 값
  • hash: 주소의 # 문자열 뒤의 값 (주로 History API 가 지원되지 않는 구형 브라우저에서 클라이언트 라우팅을 사용할 때 쓰는 해시 라우터에서 사용합니다.)
  • state: 페이지로 이동할때 임의로 넣을 수 있는 상태 값
  • key: location 객체의 고유 값, 초기에는 default 이며 페이지가 변경될때마다 고유의 값이 생성됨

여기서 쿼리스트링을 파싱하는 작업을 해야하는데 qs나 querystring 패키지를 설치해서 처리할수있다.

하지만~ v6에서는 useSearchParms 라는 Hook을 통해 쉽게 다룰수있다.

About.jsuseSearchParams

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

const About = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const detail = searchParams.get('detail');
  const mode = searchParams.get('mode');

  const onToggleDetail = () => {
    setSearchParams({ mode, detail: detail === 'true' ? false : true });
  };

  const onIncreaseMode = () => {
    const nextMode = mode === null ? 1 : parseInt(mode) + 1;
    setSearchParams({ mode: nextMode, detail });
  };

  return (
    <div>
      <h1>소개</h1>
      <p>리액트 라우터를 사용해 보는 프로젝트입니다.</p>
      <p>detail: {detail}</p>
      <p>mode: {mode}</p>
      <button onClick={onToggleDetail}>Toggle detail</button>
      <button onClick={onIncreaseMode}>mode + 1</button>
    </div>
  );
};

export default About;

useSearchParams 은 배열타입 값을 반환한다.

첫번째 원소는 쿼리파라미터를 조회하거나 수정하는 메서드가 담긴 객체를 반환하고

get으로 조회, set으로 업데이트가 가능하다. 조회시 존재하지않는다면 null 로 조회된다.

두번째 원소는 쿼리파라미터를 객체 형태로 업데이트 할수있는 함수를 반환한다.

쿼리파라미터는 문자열타입이기때문에 true, false 등 따움표를 통해서 감싸야되고 숫자를 다뤄야되면 parseInt 를 사용해야된다.

5. 중첩된 라우트

라우트 컴포넌트 자식으로 중첩되게 라우트를 설정해주고

부모 라우트 컴포넌트로 들어가 Outlet 이라는 컴포넌트를 사용하면 중첩된 라우트가 보여지게된다.

5.1 공통 레이아웃 컴포넌트

중첩된 라우트와 Outlet 은 공통적으로 보여줘야하는 레이아웃에 사용할수있다.

웹페이지의 헤더를 보여줄때 헤더를 생성해서 넣어주게되면 공통레이아웃을 적용시킬수있따.

5.2 index props

Route 컴포넌트에는 index props 가 존재한다.

index는 상위 라우트와 경로를 일치하지만, 이후에 경로가 주어지지 않았을때 라우트를 설정할대 사용한다.

path = “/” 와 동일한 역활을 하며 명시적으로 표현하는 방법

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

라우팅작업에 사용할수있는 API 를 제공한다.

6.1 useNavigate

Link 컴포넌트를 사용하지않고 다른페이지로 이동하는 상황에 사용하는 Hook

6.2 NavLink

링크에서 사용하는 경로가 현재 라우트 경로와 일치하는경우 스타일, CSS 클래스를 적용시키는 컴포넌트이다.

6.3 NotFound 페이지 생성

정의하지않은 경로로 진입했을때 보여주는 페이지를 생성한다.

NotFound 컴포넌트를 생성하고 Route 로 연결할때 path= “ * ” 를 정의하고 마지막에 작성하면된다.

**App.js**

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

const App = () => {
  return (
    <Routes>
      <Route path="/" element={<Layout />}>
        <Route index element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/profiles/:username" element={<Profile />} />
      </Route>
      <Route path="/articles" element={<Articles />}>
        <Route path=":id" element={<Article />} />
      </Route>
      **<Route path="*" element={<NotFound />} />**
    </Routes>
  );
};

export default App;

6.4 Navtgate 컴포넌트

화면을 보여주는순간 다른페이지로 이동하고싶을때 ,

페이지를 리다이렉트 하고싶을때 사용한다.

ex ) 로그인안됬으면 → 로그인페이지로 이동

7. 정리

라우터를 사용해 여러기능들이 추가된 프로젝트는 자바스크립트 용량이 매우커진다.

이를해결하기위해서는 코드스플리팅이 필요하다 이건 추후에 배우겠다

React-Router 의 공식문서

https://reactrouter.com/docs/en/v6

반응형