웹 렌더링
SPA (Single Page Application)
SPA(Single Page Application)는 단일페이지로 기존의 서버 사이드 렌더링과 비교할 때, 배포가 간단하며 네이티브 앱과 비슷한 사용자 경험을 제공한다는 장점이 있습니다.
SPA는 웹 앱에 필요한 모든 정적 리소스를 처음에 한번 다운로드합니다. 페이지 간 이동시, 페이지 갱신에 필요한 데이터만을 JSON으로 전달받아 페이지를 갱신하므로 전체적인 트래픽을 감소시킬 수 있고, 전체 페이지를 다시 렌더링하지 않고 변경되는 부분만을 갱신하므로 새로고침이 발생하지 않아 네이티브 앱과 유사한 사용자 경험을 제공할 수 있습니다.
그러나, SPA는 처음에 모든 정적 리소스를 한번 다운로드하기 때문에 초기 구동속도가 느린편입니다. 또한 SEO(검색엔진 최적화) 문제가 존재합니다. SPA는 서버 렌더링 방식(SSR)이아닌 자바스크립트 기반 비동기 모델(클라이언트 렌더링 방식:CSR)입니다. 처음 받은 웹페이지의 소스코드가 거의 비어있어 검색이 잘 되지 않을 수있습니다. 그러나 React나 Angular 등의 프레임워크는 서버 렌더링(SSR)을 지원하는 SEO 기술이 이미 존재합니다.
MPA (Multi Page Application)
MPA(Multi Page Application)는 여러 페이지를 만들고, 각 요청에 따라 적절한 페이지를 보여주는 방식으로 새로운 페이지 요청 시 마다 정적 리소스가 다운로드 되고 전체 페이지를 다시 렌더링하므로 새로고침이 발생되어 사용성이 좋지 않습니다. 또 페이지에서 필요 없는 부분을 포함하여 전체를 갱신하기 때문에 비효율적입니다.
그러나, MPA의 장점은 SPA와 달리, SEO에 친화적입니다. 검색 사이트에 노출되는 것이 중요한 웹사이트라면 MPA 구조로 개발하는 것이 좋습니다. 또한 서버에서 이미 렌더링한 결과를 가져오기 때문에 SPA와 달리 첫 로딩이 짧습니다.
항목 | MPA | SPA |
페이지 수 | 여러개 | 한개 |
초기 구동 속도 | 빠름 | 느림 |
트래픽 용량 | 큼 | 작음 |
SEO 최적화 | 강함 | 약함 |
사용자 경험 | 자연스러움 | 깜박거림(새로고침) |
새로운 페이지 요청 | 전체 페이지 다운/렌더 | 필요한 부분 다운/렌더 |
렌더링 방식 | 서버 사이드 렌더링(SSR) | 클라이언트 사이드 렌더링(CSR) |
Routing
라우팅이란, 사용자가 요청한 URL 에 따라 해당 URL에 맞는 페이지를 보여주는 것으로 가장 많이 쓰이는 라이브러리는 React Router가 있다.
리액트 라우터(React Router)
개발자가 주소별로 다른 컴포넌트를 보여주기 위해 사용하는 라이브러리다.
여러 환경에서 동작할 수 있도록 여러 종류의 라우터 컴포넌트를 제공한다.
주요 컴포넌트로 BrowserRouter/ Routes/ Route/ Link/ createBrowserRouter가 있다.
먼저 리액트라우터 라이브러리를 사용하기 위해서
$npm i react-router-dom@6 #버전6 지정 설치
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import MainPage from './pages/MainPage';
import NotFound from './pages/NotFound';
import ProductPage from './pages/ProductPage';
import Header from './components/Header';
import ProductDetailPage from './pages/ProductDetailPage';
import Photo from './pages/Photo';
function App() {
return (
<div className="App">
<BrowserRouter>
<Header />
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/products" element={<ProductPage />} />
<Route path="/products/:productId" element={<ProductDetailPage />} />
<Route path="/photos" element={<Photo />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
위 코드는 React Router 라이브러리를 이용해 라우팅을 구현한 코드 입니다. 라우팅은 웹 애플리케이션 내에서 페이지 간의 이동 및 네비게이션을 관리하는 데 사용됩니다.
먼저, 코드 상단에서 필요한 React 및 React Router 관련 모듈을 가져옵니다.
<BrowserRouter>컴포넌트:이 컴포넌트는 React Router의 중요한 부분으로 웹 애플리케이션 내에서 라우팅을 처리합니다. <BrowserRouter>는 HTML5 Historu API를 사용하여 URL을 관리하며, 브라우저의 주소 표시줄과 상호작용합니다. 새로고침을 하지 않아도 새로운 컴포넌트를 렌더링 해주는 기능을 담당하고 URL마다 컴포넌트가 바뀔 때 이때 바뀌는 부분의 최상단에 위치해야 합니다.
<Routes>컴포넌트: 이 컴포넌트는 애플리케이션의 경로와 뷰를 정의하는 곳입니다. 각 경로와 해당 컴포넌트가 연결됩니다.
<Route>컴포넌트: 이 컴포넌트는 특정 경로에 대한 매칭을 나타내며, 'element' prop을 사용하여 해당 경로로 이동할 때 렌더링될 컴포넌트를 지정합니다. (path => 경로/ element => 연결할 컴포넌트)
예제 경로 및 컴포넌트:
- /: <MainPage /> 컴포넌트는 홈 페이지를 나타냅니다.
- /products: <ProductPage /> 컴포넌트는 제품 목록 페이지를 나타냅니다.
- /products/:productId: <ProductDetailPage /> 컴포넌트는 특정 제품의 세부 정보를 나타내며 동적으로 productId를 받아 특정 제품을 표시합니다.
- /photos: <Photo /> 컴포넌트는 사진 페이지를 나타냅니다.
- *: <NotFound /> 컴포넌트는 어떤 경로에도 일치하지 않는 경우에 표시됩니다.
import React from 'react';
import { Link } from 'react-router-dom';
export default function NotFound() {
return (
<div>
<h1>NotFound</h1>
<Link to={'/'}> 홈으로 이동하기 </Link>
{/* a태그는 처음부터 다불러옴 */}
{/* <a href="http://localhost:3000">a 태그로 홈 이동</a> */}
</div>
);
}
코드 상단에서 React와 'Link' 컴포넌트를 가져옵니다. Link 컴포넌트는 React Router의 일부로, 클릭 시 다른 경로로 이동할 수 있는 링크를 생성하는 데 사용됩니다.
<Link to={'/'}> 홈으로 이동하기 </Link>: 이 부분은 React Router의 Link 컴포넌트를 사용하여 "홈으로 이동하기"라는 텍스트가 표시된 하이퍼링크를 생성합니다. 'to' prop은 링크가 이동할 경로를 지정합니다.
주석으로 처리된 <a>태그는 Link 컴포넌트 대신 일반 HTML <a>태그를 사용했을 때 예시입니다. 하지만, React Router의 'Link'컴포넌트를 사용하는 것이 권장되며 이 컴포넌트를 사용하면 페이지 간의 부드러운 전환 및 라우팅이 가능해집니다. (페이지 전환 방지)
import React from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { productInfos } from '../components/ProductList';
export default function ProductDetailPage() {
// const parameter = useParams();
//console.log(parameter); //{productId: '1'} -> params 는 string 형식으로 받아짐
const { productId } = useParams(); //객체 구조분해해서 가져오기
console.log(productId); //'1'->string
console.log(productInfos);
const productInfo = productInfos.find(
(product) => product.id === Number(productId)
);
// 밑에 두개 똑같음
console.log(productInfo);
console.log(productInfos[Number(productId) - 1]);
const navigate = useNavigate();
return (
<div>
<h1>Product Detail Page</h1>
<button onClick={() => navigate(-1)}>뒤로가기</button>
<button onClick={() => navigate('/')}>홈으로 이동하기</button>
<ul>
<li>상품번호: {productInfo.id}</li>
<li>상품명:{productInfo.name} </li>
<li>판매자: {productInfo.email}</li>
<li>상세설명: {productInfo.body}</li>
</ul>
</div>
);
}
예제 코드 상단에 React Router의 'useParams' 'useNavigate' 훅을 가져옵니다.
useParams() 훅: 'useParams 훅을 사용하여 현재 경로의 URL 매개변수를 추출합니다. 이 경우, 'productId'라는 URL 매개변수를 가져와 객체 구조분해를 사용하여 변수'productId'에 할당합니다.
useNavigate() 훅: 'useNavigate'훅을 사용하여 라우팅을 처리하는 함수 'navigate'를 가져옵니다.
import React from 'react';
import { useSearchParams } from 'react-router-dom';
export default function MainPage() {
const [searchParams, setSearchParams] = useSearchParams();
console.log(searchParams.get('mode')); //xxx.get('키값');
return (
<div className={['Main', searchParams.get('mode')].join(' ')}>
<h1>MainPage</h1>
<button
onClick={() => {
setSearchParams({ mode: 'Dark' });
}}
>
Dark Mode
{/* http://localhost:3000/?mode=Dark -> 쿼리스트링 추가됨 */}
{/* 쿼리 사용 -> 검색어 */}
</button>
</div>
);
}
이 컴포넌트는 URL의 쿼리매개변수를 이용하여 페이지의 모드를 변경할 수 있는 간단한 예제입니다.
먼저 코드 상단에 React Router의 'useSearchParams'훅을 가져옵니다.
useSearchParams() 훅 : 'useSearchParams()' 훅을 사용하여 현재 URL의 쿼리 매개변수를 가져오고 'setSearchParams'함수를 사용하여 쿼리 매개변수를 설정할 수 있는 'searchParams'배열과 함수를 반환합니다.
'searchParams.get('mode')' : 'searchParams' 배열에서 'mode'라는 키에 해당하는 값을 가져와서 출력합니다. 이렇게 함으로써 현재 모드를 표시하고, 페이지가 로드될 때 URL에서 'mode'쿼리 매개변수 값을 가져옵니다.
'SeSAC' 카테고리의 다른 글
2차 프로젝트 회고 [열줌쉬어] (4) | 2023.11.20 |
---|---|
[SeSACXCodingOn] 웹풀스택과정 14W_02 : React hook form (4) | 2023.10.16 |
[SeSACXCodingOn] 웹풀스택과정 13W_02 : 리액트 (3) (0) | 2023.10.11 |
[SeSACXCodingOn] 웹풀스택과정 12W_03 : 리액트 (2) (0) | 2023.10.06 |