Chapter1. React SPA
1-1. React SPA
Chapter2. React Router
2-1. React Router
전통적인 웹사이트의 한계와 단점 때문에 SPA가 등장함
유저가 한 웹사이트내에서 다른 웹페이지로 이동할 때마다 서버로부터 html 파일로 된 "페이지 전체"를 불러와야함(MPA)
=> 오래 걸림, 화면이 "깜빡임" => 사용자 입장에서 느린 반응성 => 사용자 경험 질 저하
=> 페이지 이동할 때마다 페이지 전체를 불러오다보니 Header나 Nav 같은 중복되는 요소를 매번 부르면,, 서버와의 불필요한 트래픽 발생
페이지 전환할 때 HTML 문서 전체가 아닌, 업데이트에 필요한 데이터만 서버에서 전달받아 이 데이터를 JavaScript가 동적으로 HTML 요소를 생성해서 화면에 보여줌
서버로부터 완전히 새로운 페이지를 불러오는 것이 아니라, 화면을 업데이트하기 위해 필요한 데이터만 서버에서 전달받아
브라우저에서 해당하는 부분만 업데이트하는 방식으로 작동하는 웹 애플리케이션이나 웹 사이트
사용자의 행동에 빠르게 반응함 => 사용자와의 빠른 상호작용이 가능함
서버 과부하 문제 완화 => 요청받은 데이터만 넘겨주면 되기 때문임
화면이 깜빡이지 않음 => 더 나은 사용자 경험 제공
SPA 대표사례
Youtube, facebook, Gmail, airbnb, Netflix
JS파일 크기가 큼 => 첫 화면 로딩 시간이 길어짐
검색엔진 최적화 bad
구글, 네이버 같은 검색 엔진은 html 문서 내의 각종 태그나, 링크를 분석함.
SPA의 경우, html파일이 비어 있다보니 검색 로봇이 충분한 자료를 수집하지 못함
따라서, 검색 노출이 중요한 웹 애플리케이션은 대응책을 따로 마련해야 => 개발의 복잡도 증가
검색엔진 최적화
구글이나 네이버 같은 검색엔진이 자료를 수집하기 좋도록 웹 페이지를 구성하는 것
디자인 들어가기 전 단계
선(wire)를 이용해 윤곽선(frame)을 잡는 것
=> 웹페이지의 레이아웃과 UI요소 등에 대한 뼈대
=> 디자인 컨셉과 사이트 기능에 대한 이해할 수 있음
데모 시연, 평가를 위한 최소한의 기능만 담은 모형
데스크톱, 스마트폰의 프레임을 덧씌워 직관적으로 이해하기 쉽게 디자인한 것
바로 페이지를 만들기보다, 어떤 컴포넌트를 만들고 이들을 어떻게 조합할지부터 구상해야 함
<Header />
와 그의 자식: <Search/>
, <Setting/>
Header 컴포넌트는 항상 화면 상단에 위치함.
=> 한 번만 만들어서 모든 페이지에서 사용하도록 설계로직 작성
<ContentsList />
와 그의 자식 : <Content/>
화면 중앙의 ContentsList 컴포넌트는 영상을 담는 역할을 함
그 안에는 동일한 레이아웃의 영상물들이 반복적인 형태로 존재함 => 자식 Content 컴포넌트를 한 번만 만들어 재사용
<Content />
: 가장 작은 단위의 컴포넌트, 가장 다양한 정보를 담고 있음Content 컴포넌트 상단 : Thumbnail
Content 컴포넌트 중앙 : Avatar, 영상소개제목
Content 컴포넌트 하단 : 채널이름, 조회수, 업로드한날짜
Content 컴포넌트는 영상과 관련된 데이터를 입력받아(객체형태{속성&값}), UI에 맞게 화면에 출력해 줌
근데 이 데이터는 해당 영상을 눌러 시청하고 있을 때도, 다른 영상을 시청할 때 추천영상으로서 대기 목록에 뜰 때도 동일한 내용이 화면에 출력됨
어떤 상태로 있느냐에 따라 출력되는 위치만 조금씩 달라질 뿐임
컴포넌트가 각자 고유의 기능을 가지고 있다는 정의? 맞는 말이지만, 더 고차원의 리액트 개발자라면,,
그 애플리케이션 안에서 다뤄지는 데이터를 컴포넌트들끼리 보다 유기적으로 주고받을 수 있도록 설계할 수 있어야 함
SPA로 하나의 웹 문서가 아니라, 하나의 웹 애플리케이션을 개발할 수 있다.
SPA는 자바스크립트 의존적이다.
SPA는 하나의 페이지를 가지고 있지만 사실 한 종류의 화면만 사용하지 않음
이 화면에 따라 "주소"도 달라짐
->이렇게 다른 주소에 따라 다른 뷰를 보여주는 과정을 경로에 따라 변경한다.
라는 의미로 라우팅(Routing)
이라 함
React 자체에는 이런 기능이 없음 => React Router라는 라이브러리로 해결
router | route matchers | route changers |
---|---|---|
BrowserRouter | Routes Route | Link |
라우터 역할 | 경로를 매칭하는 역할 | 경로를 변경하는 역할 |
이 컴포넌트들을 사용하기 위해서는 React Router 라이브러리에서 따로 불러와야 함
=> app.js 상단에 복붙ㄱ
import { BrowserRouter, Routes, Route, Link } form "react-router-dom";
-웹 애플리케이션에서 페이지를 새로고침하지 않고도 주소를 변경할 수 있게 해줌 => HTML5의 History API를 사용하기 때문
BrowserRouter가 상위에 작성되어 있어야 React Router의 컴포넌트들을 사용할 수 있음
//app.js 상단
import { BrowserRouter, Routes, Route, Link } form "react-router-dom";
function App() {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
Home
</li>
<li>
Mypage
</li>
<li>
Dashboard
</li>
</ul>
</nav>
</div>
</BrowserRouter>
);
}
export default App;
index.js에 넣어도 사용가능함
-index.js
= 리액트돔 렌더하는 공간
= jsx문법으로 쓴 app.js 랑 html 의 연결하고 렌더 ㄱ하는 공간
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(<BrowserRouter><App/></BrowserRouter>, document.querySelector('#root'));
: 경로 매칭해주는 역할
-<Routes>
,<Route>
는 App()함수의 <BrowserRouter>
컴포넌트 안에 집어넣는다.
-<Routes>
컴포넌트는 여러 <Route>
컴포넌트를 감싸고, 그중 경로가 일치하는 단 하나의 라우터만 렌더링 시키는 역할
-<Routes>
를 사용 안하면 매칭되는 모든 요소를 렌더링함
-<Route>
컴포넌트는 path 속성으로 해당 path 에서 어떤 컴포넌트를 보여줄지 정함
<Route path="/mypage" element={<Mypage />} />
단, <Link>
컴포넌트가 정해주는 URL 경로와 일치하는 경우에만 작동함.
function App() {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
Home
</li>
<li>
Mypage
</li>
<li>
Dashboard
</li>
</ul>
</nav>
<Routes>
{/* 경로는 path, 컴포넌트는 element로 연결 */}
<Route path="/" element={<Home />}/>
<Route path="/mypage" element={<MyPage />}/>
<Route path="/dashboard" element={<Dashboard />}/>
{/* 사용자가 저의하지 않은 경로(주소)로 접속을 시도할때 보여줄 컴포넌트 */}
<Route path="*" element={<Home />}/>
</Routes>
</div>
</BrowserRouter>
);
}
:경로를 연결해 주는 역할
각 컴포넌트 바깥에 to 속성으로 Route의 path 속성과 일치하는 주소 작성
페이지 전환을 통해 페이지를 새로 불러오지 않고 애플리케이션을 그대로 유지하여 페이지의 주소만 변경 (HTML5 History API를 이용)
function App() {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link> {/* Link의 to속성으로 path 주소 연결 */}
</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 />}/>
<Route path="*" element={<Home />}/>
</Routes>
</div>
</BrowserRouter>
);
}
ReactDOM으로 렌더를 시키게 되면 <Link>
컴포넌트는 <a>
요소로 바뀜
<a>
요소는 새로고침 현상이 일어나지만 <Link>
컴포넌트는 페이지 전환을 방지하는 기능이 내장되어 있기 때문에 <Link>
사용
: 특정 행동을 했을 때 해당 주소로 이동시켜주는 역할
import { useNavigate } from "react-router-dom";
function MypageForm() {
let navi = useNavigate();
function handleClick() {
if(로그인한 상태) {
navi('/mypage');
} else {
navi('/login');
}
}
return <button onClick={handleClick}>마이페이지</button>
}
로그인이 되어 있을 경우 버튼을 누르면 navigate('/mypage')
가 실행되어 mypage로 이동함
useNavigate
는 함수 호출을 통해 특정 조건에 따라 페이지를 이동할 수 있음
react-router 라이브러리 설치하기
npm install react-router-dom@^6.3.0