[POBTIL] 8일차

SWP·2022년 5월 9일
0

POBTIL

목록 보기
8/21
post-thumbnail

프리온보딩


리액트 라우터 돔v6

https://velog.io/@velopert/react-router-v6-tutorial

라우팅이란?

사용자가 요청한 URL에 따라 알맞는 페이지를 보여주는 것을 의미합니다.
여러 페이지로 구성된 웹 애플리케이션을 만들 때 페이지별로 컴포넌트들을 분리해가면서 프로젝트를 관리하기 위해 필요한 것이 바로 라우팅 시스템입니다.

리액트 라우터는 가장 인기있고, 라우팅 기능만을 집중한 라이브러리로, 사용하면 손쉽게, 안정적으로 리액트 라우터로 싱글 페이지 애플리케이션 (Single Page Application)을 만들 수 있습니다.

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

인터랙션이 많은 요즘, 페이지를 보여주어야 할 때마다 서버 측에서 모든 준비를 한다면 그만큼 서버의 자원을 사용하는 것이고, 트래픽도 더 많이 나올 수 있기 때문이죠.
리액트 같은 라이브러리를 사용해서 뷰 렌더링을 사용자의 브라우저가 담당하도록 하고, 우선 웹 애플리케이션을 브라우저에 불러와서 실행시킨 후에 사용자와의 인터랙션이 발생하면 필요한 부분만 자바스크립트를 사용하여 업데이트하는 방식을 사용하게 됐습니다.

기술적으로는 한 페이지만 존재하는 것이지만, 사용자가 경험하기에는 여러 페이지가 존재하는 것 처럼 느낄 수 있습니다. 액트 라우터와 같은 라우팅 시스템은 브라우저의 History API를 사용하여 브라우저의 주소창의 값만 변경하고 기존에 페이지에 띄웠던 웹 애플리케이션을 그대로 유지하면서 라우팅 설정에 따라 또 다른 페이지를 보여주게 됩니다.

설치

yarn add react-router-dom

페이지 이동

import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { Movie , BookMark } from "../pages";

const Router = () => {
  return (
    <BrowserRouter>
        <Routes>
          <Route path='/*' element={<Movie />} />
          <Route path='/bookmark' element={<BookMark />} />
        </Routes>
    </BrowserRouter>
  );
};

export default Router;

BrowserRouter라는 컴포넌트를 사용하여 감싸면 됩니다. 이 컴포넌트는 웹 애플리케이션에 HTML5의 History API를 사용하여 페이지를 새로 불러오지 않고도 주소를 변경하고 현재 주소의 경로에 관련된 정보를 리액트 컴포넌트에서 사용할 수 있도록 해 줍니다.
Routes 컴포넌트 내부에서 Route 컴포넌트가 사용되어야 합니다.
Route 라는 컴포넌트를 통해 브라우저 주소 경로에 따라 우리가 원하는 컴포넌트를 보여주기 위해서 라우트 설정,

<Link to="/bookmark">즐겨찾기</Link>

페이지 이동은 a태그가 아닌 Link 컴포넌트 이용 왜냐하면, a 태그를 클릭하여 페이지를 이동할 때 브라우저에서는 페이지를 새로 불러오게 되기 때문입니다.
Link 컴포넌트 역시 a 태그를 사용하긴 하지만, 페이지를 새로 불러오는 것을 막고 History API를 통해 브라우저 주소의 경로만 바꾸는 기능이 내장되어 있습니다.

URL 파라미터와 쿼리스트링

URL 파라미터

페이지 주소를 유동적인 값을 사용해야 할 때

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

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

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

const params = useParams()

URL 파라미터는 /profiles/:username/:field 와 같은 형태 :를 사용해 설정하고
useParams()훅을 이용하면 url파라미터를 객체 형태로 조회할 수 있습니다

쿼리스트링

 const location = useLocation(); 

useLocation()훅을 현재 사용자가 보고있는 페이지의 정보를 지닌 객체를 반환

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

const [searchParams, setSearchParams] = useSearchParams();

v6부터 useSearchParams() Hook을 사용하여 쿼리스트링을 쉽게 파싱

중첩된 라우트

      <Route path="/articles" element={<Articles />}>
        <Route path=":id" element={<Article />} />
      </Route>
import { Link, Outlet } from 'react-router-dom';

const Articles = () => {
  return (
    <div>
      <Outlet />
      <ul>
        <li>
          <Link to="/articles/1">게시글 1</Link>
        </li>
        <li>
          <Link to="/articles/2">게시글 2</Link>
        </li>
        <li>
          <Link to="/articles/3">게시글 3</Link>
        </li>
      </ul>
    </div>
  );
};

Outlet 이라는 컴포넌트를 사용하면 Route 의 children 으로 들어가는 JSX 엘리먼트를 보여주는 역할

공통 레이아웃 컴포넌트

Home, About, Profile 페이지에서 상단에 헤더를 보여줘야 하는 상황을 가정해봅시다.

레이아웃컴포넌트만들고

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

const Layout = () => {
  return (
    <div>
      <header style={{ background: 'lightgray', padding: 16, fontSize: 24 }}>
        Header
      </header>
      <main>
        <Outlet />
      </main>
    </div>
  );
};

export default Layout;
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 Profile from './pages/Profile';

const App = () => {
  return (
    <Routes>
      <Route element={<Layout />}>
        <Route path="/" 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>
    </Routes>
  );
};

export default App;

useNavigate

useNavigate 는 Link 컴포넌트를 사용하지 않고 다른 페이지로 이동을 해야 하는 상황에 사용하는 Hook 입니다.

import { Outlet, useNavigate } from 'react-router-dom';

const Layout = () => {
  const navigate = useNavigate();

  const goBack = () => {
    // 이전 페이지로 이동
    navigate(-1);
  };

 const goArticles = () => {
  navigate('/articles', { replace: true });
}

  return (
    <div>
      <header style={{ background: 'lightgray', padding: 16, fontSize: 24 }}>
        <button onClick={goBack}>뒤로가기</button>
        <button onClick={goArticles}>게시글 목록</button>
      </header>
      <main>
        <Outlet />
      </main>
    </div>
  );
};

export default Layout;

navigate 함수를 사용할 때 파라미터가 숫자 타입이라면 앞으로 가거나, 뒤로 갑니다. 예를 들어서 navigate(-1) 을 하면 한 번 뒤로가고 navigate(-2) 를 하면 두 번 뒤로갑니다. 반대로 navigate(1) 을 하면 앞으로 한 번 갑니다. 물론, 뒤로가기를 한번 한 상태여야 합니다.

다른 페이지로 이동을 할 때 replace 라는 옵션이 있는데요, 이 옵션을 사용하면 페이지를 이동할 때 현재 페이지를 페이지 기록에 남기지 않습니다

NavLink 컴포넌트는 링크에서 사용하는 경로가 현재 라우트의 경로와 일치하는 경우 특정 스타일 또는 CSS 클래스를 적용하는 컴포넌트입니다.

import { NavLink, Outlet } from 'react-router-dom';

const Articles = () => {
  const activeStyle = {
    color: 'green',
    fontSize: 21,
  };

  return (
    <div>
      <Outlet />
      <ul>
        <li>
          <NavLink
            to="/articles/1"
            style={({ isActive }) => (isActive ? activeStyle : undefined)}
          >
            게시글 1
          </NavLink>
        </li>
        <li>
          <NavLink
            to="/articles/2"
            style={({ isActive }) => (isActive ? activeStyle : undefined)}
          >
            게시글 2
          </NavLink>
        </li>
        <li>
          <NavLink
            to="/articles/3"
            style={({ isActive }) => (isActive ? activeStyle : undefined)}
          >
            게시글 3
          </NavLink>
        </li>
      </ul>
    </div>
  );
};

export default Articles;
  

NotFound 페이지 만들기

키워드 * 이용

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;

리다이렉트 컴포넌트

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

const MyPage = () => {
  const isLoggedIn = false;

  if (!isLoggedIn) {
    return <Navigate to="/login" replace={true} />;
  }

  return <div>마이 페이지</div>;
};

export default MyPage;
profile
잘하고싶다...

0개의 댓글