[SPA] - React Router

Donggu(oo)·2022년 11월 28일
0

React

목록 보기
5/30
post-thumbnail

1. SPA(Single Page Application)


  • SPA(Single Page Application)란 서버로부터 완전한 새로운 페이지를 불러오지 않고 페이지 갱신에 필요한 데이터만 받아 그 정보를 기준으로 현재의 페이지를 업데이트함으로써 사용자와 소통하는 웹 어플리케이션이나 웹 사이트를 말한다.

  • HTML 문서 전체가 아니라 업데이트에 필요한 데이터만 받아, JavaScript가 이 데이터를 조작하여 생성한 HTML 요소를 화면에 보여주는 개발 방식을 적용했다.

1) SPA의 장점

  • 전체 페이지가 아니라 필요한 부분의 데이터만 받아서 화면을 업데이트 하면 되기 때문에 사용자와의 Interaction에 빠르게 반응한다.
  • 서버에서는 요청 받은 데이터만 넘겨주면 되기 때문에 서버 과부하 문제가 현저하게 줄어든다.
  • 전체 페이지를 렌더링 할 필요가 없기 때문에 더 나은 유저경험을 제공한다.

2) SPA의 단점

  • SPA인 경우 JavaScript 파일의 크기가 크다. 그래서 이 JavaScript 파일을 기다리는 시간으로 인해 첫 화면 로딩 시간이 길어진다.
  • 검색 엔진 최적화(SEO)가 좋지 않다. 구글이나 네이버 같은 검색 엔진은 HTML 파일에 있는 자료를 분석하는 방식으로 검색 기능을 구동하지만, SPA의 경우 HTML 파일은 별다른 자료가 없기 때문에 검색 엔진이 적절히 동작하지 못한다.

2. React Router 사용 환경 세팅


1) react-router 라이브러리 설치

  • dom 다음 부분에 @^버전명을 입력한다. (ex : 6.3.0 버전을 설치할 경우 @^6.3.0)

명령어

npm install react-router-dom@^버전

타입 스크립트 사용 시 추가 설치

npm install react-router-dom @types/react-router-dom

  • 라이브러리가 잘 설치되었다면, package.json 파일의 dependencies 항목에 react-router-dom 이라는 라이브러리가 등록된 것을 확인할 수 있다.

2) import

  • 설치 후 react-router-dom으로부터 컴포넌트를 꺼내오기 위해 App.js파일 최상단에 import 구문 작성
  • 구문
import { BrowserRouter, Routes, Route, Link } from "react-router-dom"

3. 주소에 따라 페이지 뷰 다르게 만들기


  • App.js에 라우팅을 하기 위한 React Router의 주요 컴포넌트를 세팅한다.

1) BrowserRouter

  • <BrowserRouter> 컴포넌트는 웹 애플리케이션에서 HTML5의 히스토리 API를 사용해 페이지를 새로고침하지 않고도 주소를 변경할 수 있게 해준다. 또한 <BrowserRouter> 가 상위에 작성되어 있어야 React Router의 컴포넌트들을 사용할 수 있다.
function App () {
  return (
    <BrowserRouter>  <-
      <div>
        <nav>
          <ul>
            <li>
              Home
            </li>
            <li>
             MyPage
            </li>
            <li>
              Dashboard
            </li>
          </ul>
        </nav>
      </div>
    </BrowserRouter>  <-
  )
}
  • 그리고 아래와 같이 ReactDOM의 렌더 단계인 index.js<BrowserRouter>를 넣어서 활용할 수도 있다.
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>  <-
      <App />
    </BrowserRouter>  <-
  </React.StrictMode>
);   

2) Routes, Route

  • <Routes> 컴포넌트는 여러 <Route> 컴포넌트를 감싸서 그중 경로가 일치하는 단 하나의 라우터만 렌더링을 시켜주는 역할을 한다. <Routes> 를 사용하지 않으면 매칭되는 모든 요소를 렌더링한다.
  • <Route> 컴포넌트는 path 속성을 지정하여 해당 path 에서 어떤 컴포넌트를 보여줄지 정한다. <Link> 컴포넌트가 정해주는 URL 경로와 일치하는 경우에만 작동된다.
  • <Routes><Route> 로 주소 경로와 생성한 컴포넌트를 연결해 준다.
    • <Route>path 속성을 이용하여 경로를 작성한다. 이때, 햇갈리지 않게 경로와 컴포넌트 이름을 동일하게 맞춘다.
    • <Route> 태그 안에 element 속성으로 연결하고자 하는 컴포넌트를 넣어준다.
function App () {
  return (
   <BrowserRouter>
      <div>
        <nav>
          <ul>
            <li>
              Home
            </li>
            <li>
              MyPage
            </li>
            <li>
              Dashboard
            </li>
          </ul>
        </nav>

    {/* 주소 경로와 아까 만든 3개의 컴포넌트를 연결해 줍니다. */}
       {/* Routes 컴포넌트는 Route 컴포넌트들을 감싸고 있어야 합니다. */}
        <Routes>
          {/* 경로는 path로 컴포넌트는 element로 연결해 줍니다. */}
          <Route path="/" element={<Home />} /> 
          <Route path="/mypage" element={<MyPage />} /> 
          <Route path="/dashboard" element={<Dashboard />} />
        </Routes>
      </div>
   </BrowserRouter>
  )
}
  • 만약 사용자가 지정된 주소인 “/", “/mypage”, “/dashboard” 이외의 주소로 접근하게 되면 의도한 화면이 보이지 않을 수 있다. 이럴 때 사용할 수 있는 속성이 path=”*” 이다. 지정되지 않은 주소로 접근할 시에는 이 속성이 설정되어 있는 컴포넌트를 보여주게 된다.
  • 경로를 연결해 주는 역할을 하는 컴포넌트이다. 페이지 전환을 통해 페이지를 새로 불러오지 않고 애플리케이션을 그대로 유지하여 HTML5 History API를 이용해 페이지의 주소만 변경해 준다.

ReactDOM으로 렌더를 시키게 되면 <Link> 컴포넌트는 <a> 요소로 바뀌는 모습을 볼 수 있다.

React Router에서 <a> 요소가 아닌 <Link>를 사용하는 이유는 <a> 요소는 페이지를 전환하는 과정에서 페이지를 불러오기 때문에 다시 처음부터 렌더링을 시키기 때문이다. 즉, 새로고침 현상이 일어나게 되는 것이다.
하지만 <Link> 컴포넌트는 페이지 전환을 방지하는 기능이 내장되어 있기 때문에 SPA를 구현할 수 있는 것이다.

  • <Link>to 속성을 활용하여 <Route> 컴포넌트에 설정해 준 path 주소를 연결해 줍니다.
function App() {
  return (
    <BrowserRouter>
      <div>
        <nav>
          <ul>
            <li>
    		  {/* Link 컴포넌트를 이용하여 경로를 연결합니다 */}
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/mypage">MyPage</Link>
            </li>
            <li>
              <Link to="/dashboard">Dashboard</Link>
            </li>
          </ul>
        </nav>

         <Routes>
          <Route path="/" element={<Home />} /> 
          <Route path="/mypage" element={<MyPage />} /> 
          <Route path="/dashboard" element={<Dashboard />} />
        </Routes>
      </div>
    </BrowserRouter>
  );
}

function Home() {
  return <h1>Home</h1>;
}

function MyPage() {
  return <h1>MyPage</h1>;
}

function Dashboard() {
  return <h1>Dashboard</h1>;
}

export default App;

4. Outlet 컴포넌트와 중첩 라우팅


  • 여러 페이지에서 동일하게 보여야 하는 네비게이션 메뉴를 만들려고 하면 모든 라우트 컴포넌트마다 거의 똑같은 코드를 작성해야 한다. 리액트 라우터는 이런 번거로움을 줄이고자 Outlet이란 컴포넌트를 제공한다.

  • Outlet 컴포넌트는 다른 컴포넌트들이 렌더링되는 위치를 지정해 주는 역할을 한다.

  • Outlet 컴포넌트는 다른 컴포넌트가 렌더링되는 위치를 지정해 주는 용도이므로 Outlet에 보이기 원하는 컴포넌트는 Outlet을 사용하는 컴포넌트(ex: Layout)의 자식 라우터로 구성한다.

// Layout.tsx

import Navigation from './Navigation';

export function Layout() {
  return (
    <>
      <Navigation />
      <Outlet /> 
    </>
  );
};
// Router.tsx

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

export default function Router() {
  return (
    <Routes>
      <Route path='/' element={<Layout />}>
        <Route path='/board' element={<Board />} />
        <Route path='*' element={<Error />} />
      </Route>
    </Routes>
  );
};

0개의 댓글