React Router

1. 웹 렌더링 방식 (웹 애플리케이션의 기본 개념)

SPA (Single Page Application)란?

  • 단일 HTML 파일(index.html)에서 동작하는 애플리케이션이다.

SPA 특징

  • JavaScript를 통해 HTML 요소를 동적으로 생성하고 조작한다. 사용자가 다른 페이지로 이동할 때 전체 페이지를 불러오는 것이 아니라 필요한 데이터나 콘텐츠만 받아와 동적으로 렌더링할 수 있다는 것이다.
  • 대부분의 렌더링 작업이 사용자의 브라우저 즉, 클라이언트에서 렌더링된다. 그리고 서버는 주로 API를 통해 데이터를 제공하는 역할을 한다. → 서버에서 렌더링 작업을 거의 하지 않으면서 서버의 부하가 감소한다.그리고 클라이언트와 서버간의 분리된 구조는 유연한 개발과 유지보수를 할 수 있다.
  • 단일 HTML 페이지로 이루어져 있다. React로 예를 들면 html파일은 public 폴더 안에 index.html 단 하나로 이루어져 있고, index.js에서 ReactDOM이 App 컴포넌트를 document 내부의 id값이 root인 태그 안에 렌더링 하도록 구현되어 있다.
  • 브라우저에서 새로고침 없이 빠르게 화면 전환이 가능하다. (향상된 사용자 경험)
  • React, Vue.js, Svelte와 같은 라이브러리/프레임워크를 통해 개발한다.

SPA 단점

  • SEO(검색 엔진 최적화)에 적합하지 않다. (보완방법 : 웹페이지 초기 로딩 시, 서버에서 필요한 HTML을 생성해 브라우저로 보내주는 SSR이나 사용자의 요청이 발생하기 전에 미리 특정 버전의 웹 페이지를 생성하고, 저장하는 pre-Rendering과 같은 기술로 보완할 수 있다.)
    • 검색 엔진 최적화란? 웹사이트나 웹 페이지가 검색 엔진 결과에서 더 높은 순위를 차지할 수 있도록 최적화하는 과정 → 웹사이트의 노출이 늘어 방문자와 잠재 고객 유치 가능
  • 초기 로딩시 모든 스크립트를 로드해야하기 때문에 시간이 오래걸릴 수 있다.
  • javascript가 비활성화된 상태에서는 웹사이트가 제대로 작동하지 않을 수 있다.

MPA (Multi Page Application)와 비교

  • MPA는 여러 HTML 페이지로 구성되며 요청마다 적절한 페이지를 서버에서 제공한다.

MPA 특징

  • 분리된 페이지 구조 각 페이지는 독립적으로 로드되고, 다른 페이지로 이동할 경우 서버로부터 새로운 페이지를 요청하고 받아온다. → 대규모 웹사이트와 애플리케이션에서 기능과 컨텐츠를 관리하기 쉽다.
  • 페이지 이동 시 전체 페이지가 새로고침 때문에 SPA에 비해 로딩 시간이 길어질 수 있다.
  • 서버 중심 처리 대부분의 데이터 처리 로직이 서버에서 수행되기 때문에 서버는 요청에 따라 완성된 HTML 페이지를 클라이언트에 전송한다.
  • 검색 엔진 최적화에 유리 각 페이지가 별도의 URL을 가지고 있기 때문에 검색 엔진에 의해 더 잘 인덱싱될 수 있다.

MPA 단점

  • 페이지가 많아질수록 유지보수가 복잡해질 수 있다.
  • 중복된 코드가 증가할 수 있다.
  • 각 페이지마다 필요한 파일을 다시 로드하기 떄문에 네트워크 자원을 비효율적으로 사용할 수 있다.

SSR 이란?

( Server Side Rendering ) 웹 페이지의 초기 로딩 때 서버에 필요한 모든 HTML을 생성하여 브라우저로 보내주는 기술을 말한다. (서버에서 페이지를 렌더링)

사용자가 웹사이트에 접근할때, 서버에서 최종적으로 렌더링된 페이지를 전달 함으로써 클라이언트 측에서 추가적인 데이터 로딩이나 Javascript를 실행할 필요 없이 바로 페이지를 볼 수 있다.

SSR 특징

  • 검색 엔진 최적화 개선 완전히 렌더링된 페이지를 제공하기 때문에 검색 엔진 크롤러가 페이지 콘텐츠를 효과적으로 분석하고 인덱싱 할 수 있다.
  • 빠른 첫 페이지 로드 사용자가 첫 페이지를 요청할 때 서버에서 이미 렌더링된 페이지를 받기 때문에 초기 로드가 빠르다. 그리고 저성능 장치나 느린 네트워크를 사용하고 있는 사용자에게도 빠른 초기 렌더링을 제공할 수 있다.

SSR 단점

  • 서버 부하 증가
  • 페이지 이동 시 전체 새로고침 → 사용자 경험이 다소 느려질 수 있다.
  • 클라이언트측 Javascript가 로드되고 실행될 때까지 사용자의 상호작용(버튼 클릭 등)에 대한 응답이 지연될 수 있다.

CSR 이란?

( Client Side Rendering ) 웹 페이지를 클라이언트측 즉, 브라우저에서 렌더링하는 것이다. (클라이언트 측에서 페이지를 렌더링)

서버로부터 최소한의 구조만을 가지고있는 HTML을 받아 페이지의 실제 내용과 구조는 브라우저에서 실행되는 Javascript에 의해 동적으로 생성된다.

CSR 특징

  • 브라우저에서 렌더링 모든 렌더링 작업이 사용자의 브라우저에서 이루어진다.
  • 활발한 상호작용 Javascript를 사용해 사용자와의 상호작용에 대한 동적인 변화를 새로고침 없이 부드럽고 빠르게 제공한다.
  • 서버 부하 감소 초기 페이지 요청 이후 추가적인 데이터 요청이나 페이지 갱신은 클라이언트 측에서 처리되기 때문에 서버 부하가 상대적으로 감소된다.

CSR 단점

  • 초기 로드 지연 초기 로드시 웹 애플리케이션 모든 스크립트와 리소스를 불러온 후 컨텐츠가 렌더링 되기 때문에 첫페이지 로드가 느릴 수 있다.
  • Javascript 의존성 높음 클라이언트 측에서 Javascript가 비활성화된 경우 웹 애플리케이션이 제대로 작동하지 않을 수 있다. 페이지 렌더링과 관련된 모든 처리가 사용자의 디바이스에서 수행되기때문에 디바이스의 성능에 의존적이다.
  • 검색엔진 최적화 문제 Javascript 렌더링을 지원하고 있지만 SSR에 비해 검색엔진최적호 측면에서 불리하다.

2. 라우팅(Routing)이란?

  • 사용자가 URL을 요청하면 해당 URL에 맞는 화면을 보여주는 작업이다. === 경로를 지정하는 행위
  • React에서 가장 널리 쓰이는 라우팅 라이브러리는 React Router이다.
  • React Router는 경로에 따라 컴포넌트를 동적으로 렌더링한다.

Routing의 중요성

  • 사용자 겸험 (UI)향상
  • 검색 엔진 최적화
  • 확장성과 유지보수성 향상

React Router

  • 개발자가 주소별로 다른 컴포넌트를 보여주기 위해 사용하는 라이브러리이다.
  • 여러 환경에서 동작할 수 있도록 여러 종류의 라우터 컴포넌트 제공한다.

React Router 사용 명령어

npm i react-router-dom@6  #버전6 지정 설치

3. React Router 주요 컴포넌트

<BrowserRouter></BrowserRouter>
<Routes></Routes>
<Route />
<Link></Link>
<RouterProvider />

(1) BrowserRouter

  • HTML5의 history API를 사용하여 브라우저의 주소를 감지한다.
  • 새로고침 없이 컴포넌트를 전환한다.
  • URL에 따라 렌더링할 화면을 지정하는 최상위 컴포넌트이다. 바뀌는 부분의 최상단에 위치해야 한다.
import { BrowserRouter } from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
      {/* 여기서 Routes와 Route를 사용 */}
    </BrowserRouter>
  );
}

(2) Routes와 Route

  • Routes는 경로에 맞는 컴포넌트를 렌더링하기 위한 컨테이너이다.
  • Route는 각 경로(path)와 연결된 컴포넌트를 지정한다.
    • path: URL 경로
    • element: 렌더링할 컴포넌트
import { Routes, Route } from "react-router-dom";

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

  • HTML <a> 태그와 비슷하지만, 새로고침 없이 경로를 변경한다.
  • 페이지 전환 시 상태를 유지할 수 있다.
import { Link } from "react-router-dom";

function Header() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </nav>
  );
}

(4) RouterProvider

  • createBrowserRouter함수로 새로운 라우터를 만들고, 라우트 설정을 담당하는 객체를 인자로 받는다.
  • createBrowserRouter를 통해 생성된 라우터 객체를 사용하여 애플리케이션 내의 라우팅 Context를 설정한다. 각 Route 객체는 특정 경로와 해당 경로에서 렌더링될 컴포넌트를 연결한다.
  • 이 기능은 주로 CSR에서 사용되지만 createServerRouter 함수를 사용할 경우에는 SSR을 구현할 수 있다.
    import { createBrowserRouter, RouterProvider } from 'react-router-dom';
    
    const router = createBrowserRouter([
      {
        path: '경로',
        element: <컴포넌트 />,
      },
      {
        path: '경로',
        element: <컴포넌트 />,
      },
      // 더 많은 라우트 등록 가능
    ]);
    
    function App() {
      return (
        <RouterProvider router={router} />
      );
    }

4. 파라미터를 사용한 동적 라우팅

  • 동적 라우팅이란? URL의 일부를 변수로 사용하는 것

(1) URL 파라미터

  • Route 컴포넌트에서 동적 경로를 작성한다.
  • : 기호를 통해 파라미터의 이름을 정의하고, 해당 위치에 입력된 값을 파라미터의 이름으로 받아와 사용할 수 있다.
  • 예: /product/:id
    • :id는 URL 파라미터이다.
    • 만약 URL 파라미터가 여러 개인 경우 /product/:id/:name 처럼 설정한다. (여러 개의 파라미터를 전달할 수 있는 이유는 useParams는 현재 URL의 동적 파라미터들을 객체 형태로 반환하기 때문이다.)
import { useParams } from "react-router-dom";

function ProductDetail() {
  const { id } = useParams(); // URL의 id 값 추출
  return <div>Product ID: {id}</div>;
}

그리고 파라미터는 React Router 라이브러리에서 제공하는 useParams Hook을 사용해 값을 사용할 수 있다.

react-router-dom에서 useParams를 import하고, 변수에 담아 사용한다.

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

const { 파라미터명 } = useParams();
const 변수명 = useParams().파라미터명;

(2) URL 쿼리스트링

  • URL에 추가적인 정보를 key-value 쌍으로 제공하는 방법이다.
  • URL 뒤에 붙는 ?key=value 형식의 쿼리를 처리한다.
  • React Router에서는 useSearchParams를 사용한다.
  • useSearchParams 는 해당 쿼리스트링을 업데이트하는 함수도 반환하기 때문에 현재 URL의 쿼리스트링 값도 업데이트할 수 있다.
import { useSearchParams } from "react-router-dom";

function SearchPage() {
  const [searchParams, setSearchParams] = useSearchParams();
  const query = searchParams.get("query"); // 'query' 파라미터 값 추출
  return <div>Search Query: {query}</div>;
}

여기서 쿼리스트링의 값을 수정하는 함수의 이름은 set으로 시작한다.

그리고 특정한 key의 value를 사용하기 위해서는 searchParams.get(key)를 통해 해당 key의 value를 받을 수 있다.


(3) 페이지 이동

  • useNavigate 훅을 사용하여 프로그램적으로 페이지를 이동할 수 있다.
import { useNavigate } from "react-router-dom";

function Login() {
  const navigate = useNavigate();

  const handleLogin = () => {
    // 로그인 처리 후 메인 페이지로 이동
    navigate("/");
  };

  return <button onClick={handleLogin}>Login</button>;
}
<button onClick={() => navigate(-1)}>뒤로가기</button>
<button onClick={() => navigate("/")}>홈으로 이동하기</button>

이렇게도 사용 가능하다!


5. React Router 실습 예제

App.js

import { BrowserRouter, Routes, Route } from "react-router-dom";
import Header from "./Header";
import Home from "./Home";
import About from "./About";
import ProductDetail from "./ProductDetail";

function App() {
  return (
    <BrowserRouter>
      <Header />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/product/:id" element={<ProductDetail />} />
      </Routes>
    </BrowserRouter>
  );
}

Header.js

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

function Header() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </nav>
  );
}

export default Header;

Home.js

function Home() {
  return <h1>Welcome to the Home Page</h1>;
}

export default Home;

About.js

function About() {
  return <h1>About Us</h1>;
}

export default About;

ProductDetail.js

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

function ProductDetail() {
  const { id } = useParams();
  return <h1>Product ID: {id}</h1>;
}

export default ProductDetail;

6. React Router의 장점

  1. SPA 구현: 브라우저 새로고침 없이 빠르게 페이지 전환 가능.
  2. 유연성: URL 파라미터, 쿼리스트링 등 다양한 기능 제공.
  3. SEO 대응 가능: React Router를 서버 사이드 렌더링(SSR)과 결합하면 SEO 문제를 해결할 수 있다.

7. React Router 정리

React Router는 SPA에서 경로에 따라 컴포넌트를 동적으로 렌더링하기 위한 필수 도구이다.

BrowserRouter, Routes, Route, Link, useParams, useNavigate 등을 활용하여 효율적인 페이지 전환동적 데이터 렌더링을 구현할 수 있다.

profile
킵고잉~

0개의 댓글