Notice
Recent Posts
Recent Comments
Link
«   2026/07   »
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
Archives
Today
Total
관리 메뉴

꽃 같은 인생

React 📌4. MPA와 SPA, Props와 State📝 본문

oz코딩스쿨/React&Redux

React 📌4. MPA와 SPA, Props와 State📝

flo-jee 2025. 2. 12. 20:02

🌟 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의 장점

  1. SEO 최적화에 유리 🔍
    • 각 페이지가 개별적인 HTML을 가지므로, 검색 엔진이 쉽게 크롤링 가능
    • 블로그, 뉴스 사이트, 검색 엔진 등에 적합
  2. 보안성이 높음 🔒
    • 페이지마다 새로운 요청이 발생하므로 보안 취약점(예: XSS, CSRF)이 상대적으로 적음
  3. 초기 로딩 속도가 빠름
    • SPA는 처음에 모든 JS 파일을 로드해야 하지만, MPA는 필요한 리소스만 가져오므로 처음 로딩이 빠를 수 있음
  4. 대규모 웹사이트에 적합 🏢
    • 수백, 수천 개의 페이지를 가지는 경우 각 페이지를 독립적으로 개발 & 유지보수 가능

MPA의 단점

  1. 페이지 이동 시마다 전체 새로고침 🔄
    • 새로운 페이지를 열 때마다 서버에서 HTML을 받아와야 하므로 UX가 SPA보다 떨어짐
  2. 서버 부하가 큼 💾
    • 매번 HTML을 새로 생성하여 전송해야 하므로 트래픽이 많아질 경우 서버 부담이 증가
  3. 프론트엔드 성능 최적화 어려움 ⚙️
    • 페이지별로 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의 장점과 단점

장점

  1. 빠른 속도 🚀
    • 페이지 전환 시 전체 HTML을 다시 로드하지 않아 로드 속도가 빠름
  2. 부드러운 UX 🎨
    • 서버 요청 없이도 즉각적인 UI 업데이트 가능
  3. 프론트엔드와 백엔드 분리 가능 🛠️
    • REST API, GraphQL 등과 조합하여 클라이언트와 서버를 독립적으로 개발 가능
  4. 캐싱 효율 증가 💾
    • 처음 한 번 로드한 후, 추가 요청 없이도 빠른 재사용 가능

단점

  1. 초기 로딩 속도가 느림
    • 앱을 처음 실행할 때, 필요한 모든 JavaScript를 로드해야 하므로 첫 페이지가 느릴 수 있음
    • 해결법: 코드 스플리팅(Chunking) 적용
  2. SEO(검색 엔진 최적화) 어려움 🔍
    • 대부분의 내용이 JavaScript에서 렌더링되므로 검색 엔진이 페이지 내용을 인식하기 어려움
    • 해결법: SSR(Server Side Rendering, Next.js 활용)
  3. 백버튼 & 새로고침 문제 🔄
    • 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에서 컴포넌트의 데이터를 다루는 두 가지 방법이 PropsState입니다.

개념 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;

📌 설명

  1. useState(0) → count의 초기값을 0으로 설정
  2. setCount(count + 1)을 실행하면 count 값이 증가
  3. 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를 변경할 수도 있음