[React] React SPA
● SPA의 등장 배경과 개념
페이지를 전환할 때, 전통적인 웹사이트는 페이지 전체를 불러온다. ( MPA (Multi Page Application) - 이러한 행위를 보통 '깜빡인다'라고 함.)
이에 반해 SPA (Single Page Application)는 중복되는 부분은 새로 불러오지 않는다.
웹사이트가 발전하며 형태가 점점 복잡해지고, 사용자와 서비스 간의 상호작용이 더 많아지게 되면서 기존의 전통적인 방식은 서버와의 불필요한 트래픽을 발생시켜 반응성을 느리게 만들었다. 이러한 상황에서 보다 나은 사용자 경험을 제공하기 위하여 개발된 방식이 바로 SPA인 것이다.
물론 SPA의 단점도 있다. SPA의 경우 자바스크립트 파일의 크기가 커서 첫 화면 로딩 시간이 길다. 그리고 HTML 파일은 거의 비어 있어 이를 이용하는 검색 엔진 최적화(SEO)가 좋지 않다.
● React Router
라우팅(Routing) : 각 메시지에서 목적지까지 갈 수 있는 여러 경로 중 한 가지 경로를 설정해 주는 과정.
즉, 다른 주소에 따라 다른 뷰를 보여주는 과정을 의미한다.
→ 리액트 자체에는 라우팅 기능이 내장되어 있지 않으므로 React Router라는 라이브러리를 많이 사용한다.
create-react-app으로 만든 리액트 프로젝트 환경에 npm명령어를 이용하여 리액트 라우터 라이브러리를 설치하면 됨.
/* react-router 라이브러리 설치 예시 */
npx create-react-app simpleroute //simpleroute 폴더에 React App 설치
cd simpleroute
npm install react-router-dom@^6.3.0 //react-router 라이브러리 설치(6.3.0 버전)
[ 리액트 라우터의 주요 컴포넌트 ]
라우터 역할 : <BrowserRouter>
경로를 매칭하는 역할 : <Routes> <Route>
경로를 변경하는 역할 : <Link>
// 위 컴포넌트들을 사용하기 위해서는
// 다음 명령어를 이용해 React Router 라이브러리에서 따로 불러와야 한다.
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
(참고) import는 필요한 모듈을 불러오는 역할을 한다.
<BrowserRouter>
: 웹 애플리케이션에서 HTML5의 History API를 사용해 페이지를 새로고침하지 않고도 주소를 변경할 수 있게 해줌.
(UI를 URL과 동기화된 상태로 유지시켜줌.)
<BrowserRouter>가 상위에 작성되어 있어야 React Router의 컴포넌트들을 사용할 수 있다.
/* 사용 예시 */
function App () {
return (
<BrowserRouter> // <--
<div>
<nav>
<ul>
<li>
Home
</li>
<li>
MyPage
</li>
<li>
Dashboard
</li>
</ul>
</nav>
</div>
</BrowserRouter> // <--
)
}
export default App;
/* ReactDOM의 렌더 단계인 index.js(자바스크립트의 시작점)에 <BrowserRouter>를 넣어도 된다. */
/* React Version 18 기준 */
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>
);
/* 두번째 방법을 사용하세요! */
(참고) import React from 'react'; 는 리액트로 작성한 코드(JSX)를 브라우저가 읽을 수 있도록 변환해 주는 부분이다.
17버전부터는 작성하지 않아도 됨!
(참고) 두 번씩 렌더링 되는 게 싫다면, StrictMode는 지워도 무방하다.
<Routes> <Route>
: <Routes> 컴포넌트는 여러 <Route> 컴포넌트를 감싸 그중 경로가 일치하는 단 하나의 라우터만 렌더링 시켜준다.
<Routes> 를 사용하지 않으면, 매칭되는 모든 요소를 렌더링한다.
: <Route> 컴포넌트는 path 속성을 지정하여 해당 path에서 어떤 컴포넌트를 보여줄지 정한다.
<Link> 컴포넌트가 정해주는 URL 경로와 일치하는 경우에만 작동된다.
(참고) Route의 경로를 path="*"로 설정하면 정의하지 않은 경로를 핸들링할 수 있다.
<Link>
: 경로를 연결해 주는 역할을 하는 컴포넌트. 페이지 전환을 통해 페이지를 새로 불러오지 않고, 애플리케이션을 그대로 유지하며 HTML5의 History API를 이용해 페이지의 주소만 변경해 준다.
(참고) <a> 요소를 사용하지 않는 이유?
<a> 요소는 새로고침 현상이 일어나기 때문.
이에 반해 <Link> 컴포넌트는 페이지 전환을 방지하는 기능이 내장되어 있어 SPA를 구현할 수 있다.
/* 사용 예시 */
function App () {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link> // Link 컴포넌트를 이용하여 경로를 연결
</li>
<li>
<Link to="/mypage">MyPage</Link>
</li>
<li>
<Link to="/dashboard">Dashboard</Link>
</li>
</ul>
</nav>
<Routes>
// 경로는 path로 컴포넌트는 element로 연결
<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;