꽃 같은 인생
React 📌4. MPA와 SPA, Props와 State📝 본문

🌟 MPA(Multi Page Application) 개념 정리 🌟
1️⃣ MPA란?
- *MPA(Multi Page Application, 다중 페이지 애플리케이션)**는 사용자가 새로운 페이지로 이동할 때마다 서버에서 새로운 HTML 파일을 로드하는 웹 애플리케이션 구조입니다.
✅ 기본 개념:
- 사용자가 요청할 때마다 서버에서 새로운 HTML, CSS, JavaScript 파일을 다운로드
- 페이지 이동 시 전체 페이지가 새로고침됨
- 과거 웹사이트에서 주로 사용하던 방식이지만, 여전히 대규모 프로젝트(쇼핑몰, 기업 웹사이트 등)에서 많이 사용됨
✅ MPA의 대표적인 예시:
- 네이버, 다음, 구글 같은 검색 엔진 기반 웹사이트
- 쇼핑몰, 블로그, 뉴스 사이트 등 다양한 페이지가 필요한 웹사이트
2️⃣ MPA의 동작 방식
MPA는 클라이언트가 요청할 때마다 서버에서 새로운 HTML 페이지를 렌더링하여 반환합니다.
🔹 MPA 요청 흐름
1️⃣ 사용자가 **www.example.com/home**을 요청
2️⃣ 서버가 해당 페이지의 HTML, CSS, JS를 클라이언트에게 전송
3️⃣ 사용자가 **www.example.com/about**으로 이동하면
4️⃣ 새로운 HTML 파일이 서버에서 로드되며 페이지가 새로고침됨
📌 MPA 예제 디렉토리 구조
/project
│── index.html (홈 페이지)
│── about.html (소개 페이지)
│── contact.html (연락처 페이지)
│── styles.css (공통 스타일)
│── scripts.js (공통 JavaScript)
│── images/ (이미지 폴더)
📌 각 페이지마다 별도의 HTML 존재
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Welcome to Home Page</h1>
<a href="about.html">About</a>
</body>
</html>
<!-- about.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>About</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>About Us</h1>
<a href="index.html">Home</a>
</body>
</html>
📌 페이지 이동 시마다 새로운 HTML 파일을 불러옴 → 전체 페이지가 새로고침됨
3️⃣ MPA와 SPA 비교
비교 항목 MPA (Multi Page Application) SPA (Single Page Application)
| 페이지 이동 방식 | 새로운 HTML을 서버에서 로드 | JavaScript로 페이지 일부만 변경 |
| 속도 | 페이지 이동 시마다 로딩 필요 | 최초 로딩 이후 빠른 속도 |
| 사용자 경험 (UX) | 페이지 이동 시 새로고침 발생 | 부드러운 전환 효과 |
| SEO 최적화 | 서버에서 HTML 제공 → SEO에 유리 | JS 기반 렌더링 → 별도 최적화 필요 (SSR 등) |
| 개발 난이도 | 백엔드 중심 개발이 쉬움 | 프론트엔드 중심 개발이 필요 |
| 적용 예시 | 검색 엔진, 쇼핑몰, 기업 홈페이지 | SNS, 대시보드, 웹앱 |
💡 간단하게 말하면,
- MPA는 전통적인 방식으로, 페이지 이동 시마다 새로운 HTML을 불러오기 때문에 SEO(검색엔진 최적화)에 강함
- SPA는 빠른 UX를 제공하지만, 검색엔진 최적화를 위해 별도의 설정(SSR, Prerendering 등)이 필요함
4️⃣ MPA의 장점과 단점
✅ MPA의 장점
- SEO 최적화에 유리 🔍
- 각 페이지가 개별적인 HTML을 가지므로, 검색 엔진이 쉽게 크롤링 가능
- 블로그, 뉴스 사이트, 검색 엔진 등에 적합
- 보안성이 높음 🔒
- 페이지마다 새로운 요청이 발생하므로 보안 취약점(예: XSS, CSRF)이 상대적으로 적음
- 초기 로딩 속도가 빠름 ⚡
- SPA는 처음에 모든 JS 파일을 로드해야 하지만, MPA는 필요한 리소스만 가져오므로 처음 로딩이 빠를 수 있음
- 대규모 웹사이트에 적합 🏢
- 수백, 수천 개의 페이지를 가지는 경우 각 페이지를 독립적으로 개발 & 유지보수 가능
❌ MPA의 단점
- 페이지 이동 시마다 전체 새로고침 🔄
- 새로운 페이지를 열 때마다 서버에서 HTML을 받아와야 하므로 UX가 SPA보다 떨어짐
- 서버 부하가 큼 💾
- 매번 HTML을 새로 생성하여 전송해야 하므로 트래픽이 많아질 경우 서버 부담이 증가
- 프론트엔드 성능 최적화 어려움 ⚙️
- 페이지별로 JS, CSS가 따로 로드되므로 전환 애니메이션 등 UI 개선이 어려움
5️⃣ MPA의 문제를 해결하는 기술
문제점 해결 방법
| 페이지 이동 시 새로고침 발생 | Ajax, Pjax 사용 (일부만 동적으로 변경) |
| 서버 부하 문제 | SSR(Server Side Rendering) 적용 |
| 프론트엔드 성능 최적화 | 프론트엔드 프레임워크 활용 (React, Vue 도입 가능) |
💡 MPA + SPA 혼합 구조도 가능!
- MPA의 SEO 강점을 살리면서 일부 페이지만 SPA처럼 동작하게 만들 수도 있음
- 예) 쇼핑몰은 상품 목록 페이지는 MPA 방식, 상품 상세 페이지는 SPA 방식
🎯 정리
✔️ **MPA(Multi Page Application)**는 페이지 이동 시마다 새로운 HTML을 로드하는 전통적인 웹 구조
✔️ 장점: SEO 최적화 유리, 보안성 높음, 대규모 웹사이트에 적합
✔️ 단점: 페이지 이동 시 새로고침 발생, 서버 부하 증가
✔️ SPA보다 개발이 쉽고 안정적이지만, UX가 부족할 수 있음
✔️ Ajax, Pjax, SSR 등을 활용하여 UX를 개선할 수 있음
💡 MPA와 SPA 중 어떤 걸 선택해야 할까?
- SEO가 중요하다 → ✅ MPA
- 빠른 UX가 필요하다 → ✅ SPA
- 둘 다 필요하다 → ✅ MPA + SPA 혼합 구조 고려
🌟 React의 SPA(Single Page Application) 구현 개념 정리 🌟
1️⃣ SPA란?
- *SPA(Single Page Application, 단일 페이지 애플리케이션)**는 하나의 HTML 파일(index.html)을 기반으로, 사용자가 다른 페이지로 이동해도 전체 페이지를 새로고침하지 않고 필요한 부분만 업데이트하는 웹 애플리케이션 구조입니다.
✅ 기본 개념:
- 페이지 이동 시 서버에서 새로운 HTML을 로드하지 않음
- JavaScript로 페이지의 내용을 동적으로 변경
- 빠른 속도와 부드러운 사용자 경험(UX) 제공
✅ 대표적인 SPA 프레임워크/라이브러리:
- React.js
- Vue.js
- Angular 등
2️⃣ React에서 SPA 구현 방법
React는 기본적으로 SPA 구조를 가지며, React Router를 사용하면 라우팅 기능까지 쉽게 구현할 수 있습니다.
🔹 1. React의 기본 SPA 구조
React 앱은 기본적으로 index.html을 기반으로 동작합니다.
📌 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React SPA</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
📌 index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
📌 App.js
import React from 'react';
function App() {
return (
<div>
<h1>Welcome to React SPA!</h1>
</div>
);
}
export default App;
- index.html에는 root라는 단 하나의 <div>만 존재
- ReactDOM.render(<App />)를 통해 index.html 안의 #root에 React 컴포넌트를 삽입
- 새로운 페이지를 불러올 때도 전체 HTML을 다시 요청하지 않고, React가 필요한 부분만 갱신함
🔹 2. React Router를 이용한 SPA 라우팅
React에서는 react-router-dom 라이브러리를 사용하여 페이지 이동을 구현합니다.
📌 설치 명령어
npm install react-router-dom
📌 라우팅 구현 예제 (App.js)
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
function Home() {
return <h1>Home Page</h1>;
}
function About() {
return <h1>About Page</h1>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Router>
);
}
export default App;
📌 설명
- BrowserRouter: React에서 라우팅을 담당하는 최상위 컴포넌트
- Link: a 태그처럼 동작하지만, 전체 페이지 새로고침 없이 이동을 처리
- Routes: 여러 개의 Route를 감싸는 컨테이너
- Route: 특정 URL 경로에 따라 렌더링할 컴포넌트 지정
3️⃣ SPA의 장점과 단점
✅ 장점
- 빠른 속도 🚀
- 페이지 전환 시 전체 HTML을 다시 로드하지 않아 로드 속도가 빠름
- 부드러운 UX 🎨
- 서버 요청 없이도 즉각적인 UI 업데이트 가능
- 프론트엔드와 백엔드 분리 가능 🛠️
- REST API, GraphQL 등과 조합하여 클라이언트와 서버를 독립적으로 개발 가능
- 캐싱 효율 증가 💾
- 처음 한 번 로드한 후, 추가 요청 없이도 빠른 재사용 가능
❌ 단점
- 초기 로딩 속도가 느림 ⏳
- 앱을 처음 실행할 때, 필요한 모든 JavaScript를 로드해야 하므로 첫 페이지가 느릴 수 있음
- → 해결법: 코드 스플리팅(Chunking) 적용
- SEO(검색 엔진 최적화) 어려움 🔍
- 대부분의 내용이 JavaScript에서 렌더링되므로 검색 엔진이 페이지 내용을 인식하기 어려움
- → 해결법: SSR(Server Side Rendering, Next.js 활용)
- 백버튼 & 새로고침 문제 🔄
- SPA는 새로고침하면 기존 상태가 초기화될 수 있음
- → 해결법: localStorage, sessionStorage, Redux 등의 상태 관리 도입
4️⃣ SPA의 문제를 해결하는 기술들
문제점 해결 방법
| 초기 로딩 속도 느림 | 코드 스플리팅 (React.lazy, Suspense) |
| SEO 최적화 어려움 | SSR (Next.js), Prerendering |
| 상태 유지 어려움 | Redux, Zustand, localStorage |
🎯 정리
✔️ React는 기본적으로 SPA 구조를 따르며, react-router-dom을 활용해 페이지 이동을 구현
✔️ SPA의 장점: 빠른 속도, 부드러운 UX, 서버와 클라이언트 분리 가능
✔️ SPA의 단점: SEO 문제, 초기 로딩 속도, 새로고침 이슈 → SSR, 코드 스플리팅 등으로 해결 가능
💡 React 기반 SPA를 더 깊이 공부하고 싶다면?
- react-router-dom의 동적 라우트(:id), useNavigate 등 추가 기능 살펴보기
- Next.js를 사용해 SSR을 적용해보기
- lazy, Suspense를 사용해 코드 스플리팅 적용해보기
🎯 React의 Props와 State 개념 정리 🎯
1️⃣ Props와 State란?
React에서 컴포넌트의 데이터를 다루는 두 가지 방법이 Props와 State입니다.
개념 Props (속성) State (상태)
| 역할 | 부모 → 자식으로 데이터 전달 | 컴포넌트 내부에서 관리하는 데이터 |
| 변경 가능 여부 | 읽기 전용(Immutable) | 변경 가능(Mutable) |
| 어디에서 관리? | 부모 컴포넌트에서 관리 | 해당 컴포넌트에서 관리 |
| 어떻게 변경? | 부모에서만 변경 가능 | useState()를 사용하여 변경 |
| 주로 언제 사용? | 부모에서 자식에게 데이터를 전달할 때 | 사용자 입력, 이벤트 등에 따라 UI 변경할 때 |
💡 쉽게 말하면?
- Props: 부모가 자식에게 주는 "선물🎁" (변경 불가능)
- State: 컴포넌트가 "자신만의 상태📦"를 가지며, 변경 가능
2️⃣ Props(속성)란?
- *Props(속성)**은 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달하는 방법입니다.
✅ 특징
- 부모 → 자식 컴포넌트로만 전달 가능
- 읽기 전용(Immutable) → 자식에서 변경할 수 없음
- 함수, 문자열, 숫자, 배열, 객체 등 다양한 데이터 전달 가능
📌 Props 예제
import React from "react";
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
function App() {
return <Greeting name="Alice" />;
}
export default App;
📌 설명
- App 컴포넌트에서 Greeting 컴포넌트에 name="Alice"를 전달
- Greeting 컴포넌트에서 props.name을 받아서 표시
📌 출력 결과
Hello, Alice!
✅ 객체를 Props로 전달하는 경우
function UserInfo(props) {
return (
<div>
<h2>Name: {props.user.name}</h2>
<p>Age: {props.user.age}</p>
</div>
);
}
function App() {
const userData = { name: "Bob", age: 30 };
return <UserInfo user={userData} />;
}
✅ Props의 기본값 설정 (defaultProps)
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
Greeting.defaultProps = {
name: "Guest"
};
function App() {
return <Greeting />; // name을 전달하지 않아도 기본값 사용
}
📌 출력 결과
Hello, Guest!
3️⃣ State(상태)란?
- *State(상태)**는 컴포넌트 내부에서 관리되는 데이터로, 변경되면 자동으로 화면이 다시 렌더링됩니다.
✅ 특징
- 컴포넌트 내부에서 관리 (변경 가능)
- 변경 시 자동으로 화면 업데이트
- React의 useState()를 사용하여 변경
📌 State 예제
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0); // 초기값 0
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
📌 설명
- useState(0) → count의 초기값을 0으로 설정
- setCount(count + 1)을 실행하면 count 값이 증가
- State가 변경되면 자동으로 화면이 다시 렌더링됨
📌 출력 결과
Count: 0
(버튼 클릭) → Count: 1 → Count: 2 ...
✅ State로 입력값 관리하기
import React, { useState } from "react";
function InputExample() {
const [text, setText] = useState("");
return (
<div>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<p>You typed: {text}</p>
</div>
);
}
export default InputExample;
📌 설명
- 사용자가 input에 입력한 값을 state로 저장
- 입력 값이 바뀌면 화면도 자동으로 업데이트됨
4️⃣ Props와 State 비교
비교 항목 Props (속성) State (상태)
| 데이터 관리 위치 | 부모 컴포넌트가 관리 | 해당 컴포넌트가 직접 관리 |
| 변경 가능 여부 | 변경 불가능 (Immutable) | 변경 가능 (Mutable) |
| 누가 변경할 수 있음? | 부모 컴포넌트에서 변경 | 컴포넌트 내부에서 변경 |
| 변경 시 렌더링? | X (변경할 수 없으므로) | O (변경되면 자동 렌더링) |
| 사용 목적 | 부모 → 자식 데이터 전달 | 컴포넌트의 동적인 데이터 관리 |
💡 정리하면?
- Props → 부모에서 내려주는 읽기 전용 데이터
- State → 컴포넌트 내부에서 변화하는 동적인 데이터
5️⃣ Props와 State 함께 사용하기
📌 부모에서 Props로 전달하고, 자식에서 State로 관리하는 예제
import React, { useState } from "react";
function ChildComponent(props) {
return (
<div>
<h2>Message: {props.message}</h2>
<button onClick={props.updateMessage}>Change Message</button>
</div>
);
}
function ParentComponent() {
const [message, setMessage] = useState("Hello!");
const updateMessage = () => {
setMessage("Hello, React!");
};
return <ChildComponent message={message} updateMessage={updateMessage} />;
}
export default ParentComponent;
📌 설명
- ParentComponent는 message state를 관리
- message 값을 props로 ChildComponent에 전달
- ChildComponent에서 버튼을 클릭하면 부모의 setMessage()가 실행되어 값이 변경됨
📌 출력 결과
Message: Hello!
(버튼 클릭) → Message: Hello, React!
💡 Props는 읽기 전용이지만, 함수를 전달하면 자식에서도 부모의 state를 변경 가능!
🎯 최종 정리
✔️ Props: 부모 → 자식으로 전달하는 읽기 전용 데이터
✔️ State: 컴포넌트 내부에서 관리하는 변경 가능한 데이터
✔️ Props는 변경할 수 없고, State는 변경 시 자동으로 렌더링
✔️ 함수를 Props로 넘겨서 부모의 State를 변경할 수도 있음
'oz코딩스쿨 > React&Redux' 카테고리의 다른 글
| React 📌6. React 컴포넌트 생명주기, Hooks📝 (0) | 2025.02.12 |
|---|---|
| React 📌5. React의 상태 변경, 조건부 렌더링, Router📝 (0) | 2025.02.12 |
| React 📌3. JSX란?📝 (0) | 2025.02.12 |
| React 📌2. React 첫걸음📝 (0) | 2025.02.12 |
| React 📌1. Node.js, nvn, npm, npx 개념 정리📝 (0) | 2025.02.12 |