일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 웹접근성
- 비트연산자
- react
- JavaScript
- 알고리즘
- TypeScript
- 제로베이스 프론트엔드 스쿨
- 프로그래머스
- 디자인
- 카드뉴스
- wai-aria
- react-query
- programmers
- html&css
- leetcode
- 정규표현식
- Today
- Total
記錄
[React 스터디] SPA, Routing 본문
01 SPA (Single Page Application)
공식문서 : https://ko.reactjs.org/docs/glossary.html
SPA(Single Page Application)는 하나의 HTML 페이지와 애플리케이션 실행에 필요한 JS, CSS 등을 모두 로드(=처음에 모든 리소스를 한 번에 다운로드한다)하는 애플리케이션으로, 서버로부터 새로운 페이지를 불러오지 않아 페이지가 다시 로드되지 않는다. 페이지 간 이동 시(=URL 변경) 페이지 갱신에 필요한 데이터만을 전달받아 페이지를 갱신해 전체적인 트래픽이 감소할 수 있고, 새로고침이 발생하지 않아 네이티브 앱과 비슷한 사용자 경험을 제공할 수 있는 장점이 있다.
위와 같은 장점이 있으나, 그에 따른 구조적 단점 또한 존재한다.
첫 번째로 초기 구동 속도가 느리다는 점이 있다. 모든 리소스를 최초 접근 시 단 한 번 다운로드하기 때문에 상대적으로 구동 속도가 느리다.
두번째로는 SEO(검색엔진 최적화) 문제가 있다. 일반적으로 SPA는 CSR(클라이언트 사이드 렌더링, Client Side Rendering) 방식으로 동작하는데, 이 방식은 자바스크립트 기반 비동기 모델로 서버로부터 데이터를 받아 뷰를 동적으로 생성하기 때문에, 처음 접속하면 빈 HTML을 보여주고, 이후에 자바스크립트를 받는 구조이기 때문에 검색엔진에서 CSR로 작성된 웹페이지 분석에 어려움이 발생한다.
02 SSR, CSR
서버 사이드 렌더링 Server Side Rendering
클라이언트(브라우저)가 서버에 매번 데이터를 요청하여 서버에서 처리하는 방식으로, 클라이언트에서 요청이 들어올 때마다(=페이지 이동 시 서버에 다른 html 데이터 요청) 매번 서버에서 새로운 화면(view)을 만들어 제공하는 것으로, 서버가 화면을 그리는 주체가 된다. 이 방식은 서버로부터 완전하게 만들어진 html 파일을 받아와 페이지 전체를 렌더링한다.
전통적인 웹페이지의 구성방식인 MPA(Multi Page Application, 여러 페이지로 구성된 웹 어플리케이션)에서 주로 사용되는 방식이다.
해당 페이지에 해당하는 문서만 전달받아 렌더링하기 때문에 초기 로딩 속도가 상대적으로 빠르며, 검색엔진 최적화(SEO)가 가능하다(모든 데이터가 이미 HTML에 담겨진 채로 브라우저에 전달되기 때문). 그러나 페이지 이동이 이루어질 때마다 데이터를 요청하기 때문에 초기 로딩 이후 페이지 이동 속도가 다소 느리고, 페이지 이동 시 깜빡임이 발생한다(매번 새로고침이 이루어지기 때문). 구조상 페이지를 요청할 때마다 서버에서 페이지를 구성하는 모든 리소스를 준비해 응답하므로 서버측의 부하가 증가할 수 있다.
또한 초기 로딩 속도가 빠른 만큼 TTV(Time to View, 사용자가 사이트를 볼 수 있는 시간)와 TTI(Time to Interact, 실제로 인터랙션이 가능한 시간) 간에 시간 간격이 발생해 화면만 로드되고 실제로 기능이 동작하지 않는 상황(=자바스크립트 파일이 로드되지 않음)이 발생할 수 있다.
클라이언트 사이드 렌더링 Client Side Rendering
클라이언트(브라우저)가 렌더링을 처리하는 주체가 되는 방식으로, 서버에서 받은 데이터를 통해 클라이언트가 화면을 그리는 방식이다. 사용자의 요청에 따라 필요한 부분만 응답 받아 렌더링한다.
SPA에서 주로 선택하는 렌더링 방식으로, html이 하나이기 때문에 새로고침이 이루어지지 않아 화면 깜빡임이 발생하지 않아 사용자에게 네이티브 앱과 유사한 경험을 제공하며, 변경된 부분에 관련된 데이터만 가져오기 때문에 서버의 부담을 줄일 수 있다. 또한 데이터를 처음에 모두 받아온 이후에 각종 동작들이 이루어지기 때문에 전반적인 사용성이 좋아진다.
그러나 서버에 첫 요청 시 전체 페이지에 대한 모든 파일을 다운로드하기 때문에 첫 페이지 로딩 속도가 SSR에 비해 다소 느리고, 이 방식은 자바스크립트를 사용해 사용자와 상호작용 후에 페이지 내용을 로드하기 때문에(=빈 HTML을 로드한 이후에 JS가 로드됨) 웹 크롤러가 페이지를 색인화하려고 하면 빈 페이지로 보이게 되어 SEO(검색엔진 최적화)에 불리하다.
03 Routing
라우팅이란 출발지에서 목적지까지의 경로를 결정하는 기능으로, 어떤 화면(view)에서 다른 화면으로 화면을 전환하는 내비게이션을 관리하기 위한 기능을 뜻한다. 화면 전환이 이루어지는 경우는 다음과 같다.
-주소창 URL 입력 시 그에 해당하는 페이지로 이동
-링크(a 태그) 클릭 시 해당 페이지 이동
-뒤로 가기, 앞으로 가기 버튼 클릭 시 사용자 방문 기록(history)의 뒤 또는 앞으로 이동
간단히 말하면, 사용자가 요청한 URL에 해당하는 페이지를 보여주는 것이 라우팅이다.
04 react-router-dom 설치 및 사용
공식문서: https://github.com/remix-run/react-router#readme
리액트 라우터는 사용자가 입력한 주소를 감지하는 역할을 하며, 여러 환경에서 동작할 수 있도록 여러 종류의 라우터 컴포넌트를 제공한다.
설치는 다음의 코드를 통해 가능하다.
//NPM
npm install react-router-dom
//yarn
yarn add react-router-dom
<Router>의 종류는 다음과 같다.
- <BrowserRouter>
- <HashRouter>
- <MemoryRouter>
- <NativeRouter>
- <StaticRouter>
이 중 주로 사용되는 라우터 컴포넌트는 BrowserRouter 이다.
BrowserRouter은 HTML5의 history API(pushState, replaceState, popstate event)를 활용하여 URL과 UI를 동기해주는 라우터로, 페이지를 새로고침하지 않고도 주소를 변경할 수 있도록 해주고, 현재 주소에 관련된 정보를 props로 조회 및 사용이 가능하도록 한다.
사용 예시는 다음과 같다.
//App.js
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Main from './components/Main'; //컴포넌트
import Blog from './components/Blog';
import Tech from './components/Tech';
import JSPage from './components/JSPage';
import ReactPage from './components/ReactPage';
import Article from './components/Article';
function App(){
return (
<BrowserRouter> //적용하고 싶은 컴포넌트의 최상위 컴포넌트를 감싸줌
<Routes>
//여러 Route를 감싸서 그 중 규칙이 일치하는 Route 단 하나만을 렌더링해주는 역할
<Route path={'/'} element={<Main />} />
//path에 경로, element에 컴포넌트를 넣어줌
<Route path={'/tech'} element={<Tech />}>
//Nested Routes -> 부모 컴포넌트에 Outlet를 사용해야 함
<Route path='jspage' element={<JSPage />} />
<Route path='reactpage' element={<ReactPage />} />
<Route path='reactpage/:dataId' element={<Article />}>
//url 파라미터 - 경로에 : 사용해 설정
</Route>
<Route path={'/blog'} element={<Blog />} />
</Routes>
</BrowserRouter>
)
}
//Main.js
import React from 'react';
import { Link } from 'react-router-dom';
export default Main = () => {
return (
<div>
<h1>Main</h1>
<Link to='/blog'>Blog</Link>
<Link to='/tech'>Technology</Link>
//to 속성에 이동할 link를 작성
</div>
)
}
//a태그를 사용하면 새로운 페이지를 불러오면서 새로고침이 발생
//Tech.js
import React from 'react';
import { Outlet, Link } from 'react-router-dom';
export default Tech = () => {
return (
<>
<div>
<h1>Technology</h1>
<Link to='/tech/jspage'>JavaScript</Link>
<Link to='/tech/react'>React</Link>
</div>
<Outlet />
//child route를 렌더하기 위해 필요(중첩된 ui 나타나도록)
</>
)
}
//ReactPage.js
import React from 'react';
import { Link } from 'react-router-dom';
export default ReactPage = () => {
//데이터 목록
return (
<div>
{datas.map(data => (
<Link to={`${data.id}`} key={data.id}> //url에 클릭한 데이터의 id가 출력
{data.title}
</Link>
))}
</div>
)
}
//Article.js
import React from 'react';
import { useParams } from 'react-router-dom'; //라우터 사용 시 파라미터 정보를 뽑아올 수 있음
export default Article = () => {
const params = useParams(); //정보를 변수에 저장
return (
<div>
<h3>#{params.dataId}</h3>
<p>React Page #{params.dataId}의 내용입니다.</p>
//파라미터값 사용
</div>;
)
}
* useNavigate
라우터 컴포넌트 내에서만 작동하며, Link 컴포넌트 사용하지 않고 다른 페이지로 이동할 때 사용하는 hook이다. replace 옵션 사용 시 페이지 이동할 때 히스토리를 남기지 않는다.
//Article.js
//useNavigate 활용 예시 추가
import React from 'react';
import { useParams, useNavigate } from 'react-router-dom';
export default Article = () => {
const params = useParams();
const navigate = useNavigate();
return (
<div>
<h3>#{params.dataId}</h3>
<p>React Page #{params.dataId}의 내용입니다.</p>
<button onClick={()=>navigate('/')}>To Main</button>
//클릭하면 Main 으로 이동하는 버튼
</div>;
)
}
참고 자료
'FRONTEND STUDY > React' 카테고리의 다른 글
React-Query (0) | 2023.02.27 |
---|---|
JSON-SERVER (0) | 2023.02.20 |
[React 스터디 - 6] 리액트 CSS 적용 방법 (0) | 2022.12.25 |
[React 스터디-5] List, Key (0) | 2022.12.18 |
[React Study - 5] Life cycle, useEffect() (0) | 2022.12.11 |