#1. Single Page Application
1. Single Page Application의 개념
1) Single Page Application이란?
- 하나의 HTML 페이지로 다수의 페이지 효과를 내는 구현 방식을 말한다.
- js 파일로 웹 페이지 화면을 변경하는 형태로 구현된다.
- Single Page Application을 줄여서 SPA 라고 부르기도 한다.
- Router를 활용해서 페이지를 구현한다.
※ Router
- 분배하는 기능을 수행하는 소프트웨어나 하드웨어를 말한다. (대표적인 하드웨어로는 공유기가 있다)
- 리액트에서 Router는 URL에 의해 컴포넌트를 분배하는 기능을 말한다.
- HTML에서 자바스크립트에 추가된 기능 중 history 객체를 통해 URL을 변조하는 기능이 있다.
- 리액트의 Router는 이 기능을 활용하여 현재 페이지의 URL을 다양하게 변조하여 각각의 컴포넌트를 분배한다.
2) 장점
- 페이지 이동 없이 JS에 의해 화면이 갱신되므로 실제로 네트워크 통신이 발생하지 않아 실행 속도가 빠르다.
- 웹 어플리케이션에 필요한 모든 정적 리소스를 최조에 한번만 다운로드 한다.
- 이후 새로운 페이지 요청 시, 페이지 갱신에 필요한 데이터만 받기 때문에 전체적인 트래픽 감소
3) 단점
- 서버가 해야할 일을 자바스크립트가 대신 하다보니 JS코드가 비대해 질 수 있다. (코드 스플리팅 기법으로 해결 가능, 코드 분할 작성)
- 하나의 HTML이므로 SEO(Search Engin Optimization)에 취약하다. (서버사이드 렌더링으로 해결 가능)
※ 검색엔진 최적화(SEO)
- 검색엔진이 이해하기 쉽도록 홈페이지의 구조와 페이지를 개발해 검색 결과를 상위에 노출될 수 있도록 하는 작업이다.
- 기본적인 작업 방식은 특정 검색어를 웹페이지에 적절하게 배치하고 다른 웹페이지에서 링크가 많이 연결되도록 하는 것이다.
2. Router 사용하기
※ create-react-app을 진행했다는 가정하에 추가진행.
1) 추가 패키지 설치하기
- 터미널에서 프로젝트를 진행할 React 폴더 주소로 이동한다.
- 해당 주소에서 아래 명령어를 수행해서 react-router-dom 패키지를 설치한다.
yarn add react-router-dom
※ react-router-dom
- SPA 앱을 만들 때 사용한다.
- URL에 따라 실행한 자바스크립트를 분기해준다.
- 세가지 비슷한 패키지가 존재하며, 각각 용도가 다르다.
- react-router : 웹 & 앱
- react-router-dom : 웹
- react-router-native : 앱
2) Router 적용하기
※ 구문추가
-1. index.js
- 상단에 아래 import 구문을 추가한다.
import { BrowserRouter } from "react-router-dom";
- .render 구문에 <BrowserRouter> 태그를 추가한다.
- history API를 사용해 URL과 UI를 동기화 하는 라우터.
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter> // BrowserRouter 태그 추가
<App />
</BrowserRouter>
</React.StrictMode>
);
-2. App.js
- 상단에 아래 import 구문을 추가한다.
import { Link, Routes, Route } from "react-router-dom";
- Link : "a" 태그와 비슷하지만, a태그는 클릭시 페이지를 새로 불러오기 때문에 사용하지 않는다.
- to 속성에 설정된 링크로 이동하고, 기록이 history 스택에 저장된다.
- Routes : 컴포넌트는 여러 Route를 감싸서 그 중 규칙이 일치하는 라우트 하나만을 렌더링 시켜주는 역할을 한다.
- Route : 컴포넌트의 속성에 설정된 URL과 현재 경로가 일치하면 해당하는 컴포넌트, 함수를 렌더링한다.
- path 속성에 경로, element 속성에는 컴포넌트를 넣어준다. 여러 라우팅을 매칭하고 싶은 경우 URL 뒤에 " /* "을 사용한다.
3) Router를 활용해서 페이지 만들기
- 리액트는 단 한개의 파일로 만들어지지 않는다.
- 여러 파일을 참조하는 구조로 페이지를 구성한다.
- index.js 파일과 App.js 파일은 공통적으로 사용되고, 나머지는 개발자 재량 (App.js에 참조한다)
- index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from "react-router-dom"; // 추가
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter> // 추가
<App />
</BrowserRouter>
</React.StrictMode>
);
- 위에서 설명했듯이 BrowserRouter를 import하고, 태그를 추가한다.
- App.js
import React from "react";
import { Link, Routes, Route } from "react-router-dom"; // 추가
import Home from "./pages/Home" // Home.js 참조
import About from "./pages/About" // About.js 참조
import Main from "./pages/Main"; // Main.js 참조
function App() {
return (
<div>
<h1>SPA Example</h1>
<hr />
{/* === 링크 구성 부분 === */}
<nav>
<Link to="/">[ Home ]</Link>
<Link to="/about">[ About ]</Link>
<Link to="/main">[ Main ]</Link>
</nav>
{/* === 페이지 역할을 할 컴포넌트를 명시하기 === */}
<Routes>
{/* 첫 페이지로 사용되는 컴포넌트의 경우 exact={true}를 명시해야 한다. */}
{/* 첫 페이지로 사용되는 컴포넌트는 path에 "/"를 권장 */}
<Route path="/" element={<Home />} exact={true}></Route>
<Route path="/about" element={<About />}></Route>
<Route path="/main" element={<Main />}></Route>
</Routes>
</div>
);
}
export default App;
- { Link, Routes, Route } 를 import 한다.
- Link는 <Link to="경로">링크명</Link> 형식으로 사용한다.
- Route는 <Route path="경로" element={컴포넌트} /> 형식으로 사용한다.
- Home.js (예시)
import React from "react";
const Home = () => {
return (
<div>
<h2>여기는 Home.js 파일 입니다.</h2>
</div>
);
};
export default Home;
- About.js (예시)
import React from "react";
const About = () => {
return (
<div>
<h2>여기는 About.js 파일 입니다.</h2>
</div>
);
};
export default About;
- Main.js (예시)
import React from "react";
const Main = () => {
return (
<div>
<h2>여기는 Main.js 파일 입니다.</h2>
</div>
);
};
export default Main;
※ 실행결과
4) 서브라우팅 사용하기
- MainSub1.js (예시)
import React from "react";
const MainSub1 = () => {
return (
<div>
<h3>여기는 Main의 서브 페이지인 MainSub1.js 입니다.</h3>
</div>
);
};
export default MainSub1;
- 서브라우팅으로 사용할 js파일 작성.
- Main.js (예시)
import React from "react";
// Main에서 서브라우팅을 사용하기 위해 다시 호출
import { Link, Routes, Route } from "react-router-dom";
import MainSub1 from "./MainSub1"; // MainSub1을 참조
const Main = () => {
return (
<div>
<h2>여기는 Main.js 파일 입니다.</h2>
{/* === 링크 구성 부분 === */}
<nav>
<Link to="sub1">[서브페이지]</Link>
</nav>
{/* === 페이지 역할을 할 컴포넌트를 명시하기 === */}
<Routes>
<Route path="sub1" element={<MainSub1 />} />
</Routes>
</div>
);
};
export default Main;
- Main.js 파일에서 서브라우팅을 구성하기 때문에 App.js 파일과 같은 구조로 작성한다.
- App.js
{/* 서브라우팅 사용 */}
{/* 하위의 모든 값을 허용할 때는 "/*"를 뒤에 붙인다 " */}
<Route path="/main/*" element={<Main />}></Route>
- App.js의 Route의 path 경로를 하위 모든 값을 허용하게 해준다.
- /main 경로 뒤에 " /* " 사용
※ 실행결과
- Main 링크를 누르면 서브페이지 링크가 생기고, 서브페이지 링크를 누르면 해당 내용이 출력된다.
5) 지정되지 않은 요청에 대한 반응
- Error404.js (예시)
import React from "react";
const Error404 = () => {
return (
<div>
<h2>요청하신 페이지는 존재하지 않습니다.</h2>
</div>
);
};
export default Error404;
- 지정되지 않은 주소를 요청시 에러 메세지를 띄운다.
- App.js
import Error404 from "./pages/Error404";
{/* path 속성 없이 Route 지정 -> 지정되지 않은 모든 요청에 반응.
단, Routes블록의 맨 마지막에 배치해야 한다. */}
<Route path="/*" element={<Error404 />} />
- 지정되지 않은 주소에 대한 반응은 <Routes> 태그 맨 마지막에 배치해야한다.
- path 경로는 모든 주소를 허용하는 " /* " 형태로 지정한다.
※ 실행결과
6) useParams
- useParams는 리액트에서 Router 사용 시 파라미터 정보를 가져와 활용할 수 있게 해준다.
- 즉, 동적라우팅이 필요할 때 사용하면 좋은 방법이다.
- WeatherData.js (예시)
const WeatherData = {
"mon": ["맑음", "맑음"],
"tue": ["비", "맑음"],
"wed": ["맑음", "흐림"],
"thu": ["맑음", "흐림"],
"fri": ["흐림", "흐림"],
"sat": ["비", "맑음"],
"sun": ["맑음", "맑음"],
};
export default WeatherData;
- 먼저 날씨정보에 대한 내용을 JSON 형태로 작성한다.
- 보통은 이미 만들어진 데이터들을 가져오는 형식으로 사용한다.
- index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from "react-router-dom"; // 라우터를 사용할 때 필수
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter> {/* <App />을 <BrowserRouter/>로 감싼다 */}
<App />
</BrowserRouter>
</React.StrictMode>
);
- BrowserRouter 를 import 시켜준다.
- <App /> 을 <BrowserRouter />로 감싼다.
- App.js
import React from "react";
import { Link, Routes, Route } from "react-router-dom";
import Weatehr from './MyWeather'; // MyWeather.js 참조
function App() {
return (
<div>
<h1>주간날씨</h1>
<hr />
<nav>
<Link to="/weather/mon">월</Link> |
<Link to="/weather/tue">화</Link> |
<Link to="/weather/wed">수</Link> |
<Link to="/weather/thu">목</Link> |
<Link to="/weather/fri">금</Link> |
<Link to="/weather/sat">토</Link> |
<Link to="/weather/sun">일</Link>
</nav>
<Routes>
<Route path="/weather/:day" exact={true} element={<Weatehr />} /> // id값 지정
</Routes>
</div>
);
}
export default App;
- MyWeather.js를 import 시켜준다.
- <Route>의 path경로에 id값을 지정해준다.
- <Route path="/weather/:day" exact={true} element={<Weatehr />} />
- 여기서는 /:day 가 id값 역할을 한다. (이 자리에 입력한 <Link> 태그의 /weateher 뒤 주소값을 가져온다)
- MyWeather.js (예시)
import React from 'react';
import { useParams } from "react-router-dom"; // useParmas hook 지정
import WeatherData from './WeatherData'; // 날씨정보 참조
const MyWeather = () => {
const params = useParams(); // 컴포넌트 내에 useParams() 선언
const {day} = params; // 비구조문법으로 파라미터값 호출
const [am, pm] = WeatherData[day]; // 파라미터 값에 따라 날씨정보 배열을 비구조문법으로 호출
return (
<div>
<h2>오전</h2>
<p>{am}</p> // 호출한 배열 변수 사용
<h2>오후</h2>
<p>{pm}</p>
</div>
);
};
export default MyWeather;
- react-router-dom의 useParams를 import 시켜준다.
- import { useParams } from "react-router-dom";
- 컴포넌트 내에 useParams( )를 선언하고, id값(파라미터)을 호출한다. (클릭하는 <Link> 경로의 파라미터값을 받아온다)
- 호출한 id값을 날씨정보 데이터 객체에 매치 시켜(key) 배열을 비구조문법으로 변수에 호출하고(value) JSX에서 변수값을 사용한다.
'국비수업 > React' 카테고리의 다른 글
[React] CSS 사용하기 (0) | 2022.04.26 |
---|---|
[React] Props (Properties) (0) | 2022.04.25 |
[React] JSX (JavaScript eXtension) (0) | 2022.04.23 |
[React] React의 기본 구조 (0) | 2022.04.21 |
[React] React의 개념 / 개발환경 구성하기 (0) | 2022.04.21 |