개발 R.I.P.

6.08 Dev.Feedback (React #2 SPA, Router)

편행 2021. 6. 8. 20:04
반응형

SPA ( Single Page Application)

 

SPA 등장 배경

 

전통적인 웹사이트에서는 사용자가 웹사이트 내의 다른 페이지로 이동하면, 브라우저가 페이지를 보여주기 위해 매번 HTML 파일로 된 "페이지 전체"를 불러와야만 했다.

Page 전환시, 전통적인 페이지 구현과 SPA의 페이지 구현

예시 그림은 동일한 페이지 전환을 보여주고 있는데,

전통적인 웹사이트는 페이지 전체를 로딩하고,

SPA는 Menu와 Footer와 같이 페이지 전환 전후에 중복되는 부분은 새로 불러오지 않는 걸 볼 수 있다. 

 

웹사이트가 보다 복잡해지고 애플리케이션의 형태를 가지게 되면서, 사용자와 서비스 사이에 더욱 많은 상호작용이 일어나게 되었다. 하지만 이때마다 Header 나 Navigation Bar 등과 같이 중복되는 요소들을 매번 불러오는 것이 서버와의 불필요한 트래픽을 발생시켰고, 이런 트래픽이 사용자 입장에서는 더 느린 반응성을 갖게 되었다.

 

이 문제점이 애플리케이션과 같은 사용자 경험을 제공하기 어렵게 만들었다.

 

이런 문제점들을 해결하여 사용자에게 쾌적한 환경에서 애플리케이션을 제공하기 위해 SPA가 등장했다.

 

SPA는 서버로부터 완전히 새로운 페이지를 불러오는 것이 아니라,

화면을 업데이트하기 위해 필요한 데이터만 서버에서 전달받아 브라우저에서 해당하는 부분만 업데이트하는 방식으로 작동하는 웹 애플리케이션이나 웹 사이트를 말한다.

 

 

SPA 의 장점

  • 페이지 전체를 렌더링 하는 것이 아니라 필요한 부분만 업데이트하기 때문에 유저의 행동에 빠르게 반응이 가능하다.
  • 서버 입장에서는 요청받은 데이터만 넘겨주면 되기 때문에 과부하 문제도 현저히 줄일 수 있다.
  • 화면 전체를 새로 렌더링 할 필요가 없기 때문에 보다 나은 유저 경험을 제공합니다.

SPA의 단점

  • Javascript의 파일이 커서 첫 화면 로딩 시간이 길다.
  • 검색 엔진 최적화(SEO)가 좋지 않다. ==> 검색 엔진이 적절히 동작하지 못한다. (최근 이 단점은 해결해나가는 중)

나중에 검색해서 내용 보충하기

Routing

앞서 말한 SPA를 구현하기 위해, Routing이라는 개념도 알아야 한다.

 

SPA는 하나의 페이지를 가지고 있지만 사실 한 종류의 화면만 사용하지 않는다.

 

또한 이 화면에 따라 "주소"도 달라지는데, 이렇게 다른 주소에 따라 다른 뷰를 보여주는 과정을 "경로에 따라 변경한다."라는 의미로 라우팅(Routing) 이라고 한다.

 

React에서 이 라우팅 기능을 갖고 있지 않아

React Router라는 라이브러리를 통해 그 기능을 구현한다.

React Router

React Router에는 주요 컴포넌트가 있다.

BrowserRouter -> 라우터 역할
Switch -> 경로를 매칭
Route -> 경로를 매칭 (Switch의 하위 요소)
Link -> 경로를 변경

위의 컴포넌트들을 사용하기 위해선 라이브러리를 따로 불러와야 하는데,
import를 사용하면 된다.

import {BrowserRouter, Switch, Route, Link} from "react-router-dom";

** 위의 import를 사용하기 위해선 당연히 라이브러리를 설치해야 한다.
$ npm install react-router-dom

일단 짧게 각 컴포넌트들이 하는 역할을 정리해봤다.

 

조금 더 디테일하게 정리해보면,

 

BrowserRouter

BrowserRouter는 웹 애플리케이션에서 HTML5의 History API (조금 더 정리 내용 보충ㅍ필요) 를 사용해 페이지를 새로고침하지 않고도 주소를 변경할 수 있는 역할을 해준다. 아래와 같이 ReactDOM의 렌더 단계인 index.js 에 넣어서 활용할 수도 있다.

BrowserRouter가 상위에 작성되어 있어야 Route 컴포넌트를 사용할 수 있다.

 

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
<BrowserRouter>
<App/>
</BrowserRouter>, document.querySelector('#root'));

Switch, Route

경로를 매칭해주는 컴포넌트이다.

  • <Switch> 컴포넌트는 여러 <Route>를 감싸서 그 중 경로가 일치하는 단 하나의 라우터만 렌더링을 시켜주는 역할을 한다. (Route의 길잡이) <Switch> 를 사용하지 않으면 매칭되는 모든 요소를 렌더링한다.
  • <Route> 컴포넌트는 path 속성을 지정하여 해당 path에 어떤 컴포넌트를 보여줄지 정한다. Link 컴포넌트가 정해주는 URL 경로와 일치하는 경우에만 작동된다.

 

Link

경로를 연결해주는 역할을 하는 컴포넌트, 페이지 전환을 통해 페이지를 새로 불러오지 않고 애플리케이션을 그대로 유지하여 HTML5 History API 를 이용해 페이지의 주소만 변경해준다.

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

React Router 에서 <a> 태그가 아닌 <Link>를 사용하는 이유는?
<a>태그는 페이지를 전환하는 과정에서 페이지를 불러오기 때문에 다시 처음부터 렌더링을 시킨다. 
즉, 새로고침을 해버리는 것이다.
하지만 <Link> 컴포넌트는 페이지 전환을 방지하는 기능이 내장 되어있기 때문에 SPA를 구현할 수 있다.
function App() {
  return (
    <BrowserRouter>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>{/* Link 컴포넌트를 이용하여 경로를 연결합니다 */}
            </li>
            <li>
              <Link to="/about">MyPage</Link>
            </li>
            <li>
              <Link to="/dashboard">Dashboard</Link>
            </li>
          </ul>
        </nav>

        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/about">
            <MyPage />
          </Route>
          <Route path="/dashboard">
            <Dashboard />
          </Route>
        </Switch>
      </div>
    </BrowserRouter>
  );
}

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

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

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

export default App;
반응형