23~24회차 React & Redux

정상희·2025년 4월 6일

코딩공부

목록 보기
33/60
post-thumbnail

현재 오즈코딩스쿨 강의를 통해 프론트엔드를 학습하고 있습니다.
본 포스트는 해당 강의에 대한 내용 정리를 목적으로 합니다.

1. React 프로그래밍

1) 선언적 프로그래밍(Declarative)

React는 선언적(declarative) 프로그래밍 방식을 따르는 대표적인 라이브러리이다.

"어떻게(How)" 특정 작업을 수행해야 하는지 지시하기보다는 "무엇(What)"결과로 얻고자 하는지를 설명하는 방식이다.

"무엇(What)"을 화면에 표시할지 JSX 문법으로 표현하면 JSX에 들어가는 데이터가 변화하면 데이터에 맞는 화면이 "결과"로 표시된다.

  • 무엇(What)을 할 것인지 선언하면, 내부적으로 알아서 처리됨.
  • React에서는 상태(State)가 변경되면 UI가 자동으로 갱신됨.
// React로 상태 기반 UI 변경 (선언형)
import { useState } from "react";

function App() {
    const [text, setText] = useState("안녕하세요!");

    return (
        <div>
            <h1>{text}</h1>
            <button onClick={() => setText("클릭하면 변경됨!")}>
                클릭
            </button>
        </div>
    );
}

✅ 장점: 코드가 직관적, 유지보수 편리
❌ 단점: 내부 동작을 이해해야 함 (초반 러닝 커브)


2) 명령적 프로그래밍(Imperative)

  • 개발자가 직접 하나하나 동작을 정의해야 함.
  • 상태(State)를 변경하려면 DOM을 직접 조작해야 함.
// Vanilla JavaScript로 버튼 클릭 시 텍스트 변경 (명령형)
const btn = document.getElementById("myButton");
btn.addEventListener("click", () => {
    const title = document.getElementById("title");
    title.innerText = "안녕하세요!";
    title.style.color = "blue";
});

✅ 장점: 로우 레벨 제어 가능, 성능 튜닝 쉬움
❌ 단점: 코드 복잡, 유지보수 어려움


3)선언적 vs 명령형 프로그래밍 비교

구분선언적 프로그래밍 (Declarative)명령형 프로그래밍 (Imperative)
설명"무엇(What)"을 원하는지 선언"어떻게(How)" 수행할지를 단계별로 명령
코드 스타일상태 기반, 데이터 흐름 중심절차적, 단계별 로직이 많음
유지보수코드가 직관적이고 유지보수 쉬움복잡한 로직으로 관리 어려움
예시 기술React, SQL, HTML, HaskellJava, C, jQuery
  • 선언적 프로그래밍 → "이렇게 되고 싶다" 선언하면 알아서 처리됨."
  • 명령형 프로그래밍 → "어떻게 할지 직접 다 짜야 함."

4) 데이터 관리: State vs Props

a. State(상태) - 컴포넌트 내부 데이터

특정 React 컴포넌트 안에서 사용하는 데이터(변경가능)
✔ 값이 변경되면 자동으로 UI가 다시 렌더링됨
✔ useState를 사용하여 상태를 관리

Class 컴포넌트


class MyComponent extends Component {
state = {상태이름: 상태값}

  ComponentMethod = () => {
    this.setState({상태이름: 새로운 상태값})
	}

  render(){
    return (표시할 요소, 컴포넌트)
  }
}

함수형 컴포넌트

function MyComponent (){
	const [상태, 상태변경함수] = useState(상태값)

	ComponentMethod = () => {
    상태변경함수(새로운 상태값)
	}
    return (표시할 요소, 컴포넌트)
  }
}

상태 변경 함수를 사용하지 않으면, React는 상태 변경을 감지하지 못한다.


예시

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0); // State 선언

  return (
      <div>
          <h1>카운트: {count}</h1>
          <button onClick={() => setCount(count + 1)}>증가</button>
      </div>
  );
}

export default Counter;

✔ count는 State
✔ setCount를 이용해 State 값을 변경
✔ 값이 변경되면 자동으로 화면이 업데이트됨

b. Props(속성) - 부모가 자식에게 데이터 전달

✔ 부모 컴포넌트에서 자식 컴포넌트로 전달하는 데이터
✔ 읽기 전용이라 자식에서 직접 변경할 수 없음(변경 불가능)
✔ 함수도 Props로 전달 가능

<자식컴포넌트 props이름 = { props } />

Class 컴포넌트(props 버전)


class 컴포넌트이름 extends Component {
render() {
  return (
    JSX 요소들
    this.props.속성이름
  );
}
}

Class 컴포넌트(super 버전)

class 컴포넌트이름 extends Component {
constructor(props) {
  super(props);
  this.state = {
    상태이름: 상태값
  };
}

메서드이름 = () => {
  this.setState({
    상태이름: 새로운상태값
  });
};

render() {
  return (
    JSX 요소들
    this.state.상태이름
    this.props.속성이름
  );
}
}
  • 클래스 컴포넌트에서도 props는 꼭 필요하며, this.props를 이용해서 받아오면 된다.

  • constructor 안에서 state 초기화

  • super(props)this.props를 사용하기 위한 필수 코드

  • 메서드나 이벤트 핸들러를 선언해서 상태 변경 가능

  • JSX 안에서 this.state, this.props 모두 사용 가능


함수형 컴포넌트

function 컴포넌트이름(받은props) {
  return (
    JSX 요소들  
    받은props.속성이름  
  );
}

const 컴포넌트이름 = (받은props) => {
  return (
    JSX 요소들  
    받은props.속성이름  
  );
};
  • 클래스 없이 간단하게 작성 가능

  • props를 인자로 받아 사용

  • state, useEffect 등은 훅(Hooks)을 사용해 다룰 수 있음

  • 읽기 쉽고 코드가 간결함

  • React의 권장 방식이며 최신 프로젝트에서 주로 사용됨


예시

function Message({ text }) { // Props 받음
    return <h1>{text}</h1>;
}

function App() {
    return <Message text="안녕하세요, React!" />; // Props 전달
}

export default App;

✔ text는 Props
✔ 부모(App)가 자식(Message)에게 값을 전달
✔ Message 컴포넌트는 받은 Props를 표시

c. State vs Props 차이점

구분StateProps
역할컴포넌트 내부에서 관리하는 데이터부모가 자식에게 전달하는 데이터
변경 가능 여부✅ 변경 가능 (setState)❌ 변경 불가 (읽기 전용)
어디서 관리?컴포넌트 내부에서 관리부모 컴포넌트에서 관리

d. State와 Props 함께 사용하기

State를 부모에서 관리하고, Props로 자식에게 전달할 수도 있다.

import { useState } from "react";

function CounterDisplay({ count }) {
    return <h1>카운트: {count}</h1>;
}

function Counter() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <CounterDisplay count={count} /> {/* State를 Props로 전달 */}
            <button onClick={() => setCount(count + 1)}>증가</button>
        </div>
    );
}

export default Counter;

countState
CounterDisplayProps로 전달
✔ 버튼 클릭 시 State 변경 → Props가 바뀌어 자동으로 UI 업데이트됨



2. SPA(Single Page Application)

SPA(싱글 페이지 애플리케이션) 는 한 개의 HTML 페이지에서 화면을 동적으로 변경하는 웹 애플리케이션이다.

1) 전통적인 웹 (MPA) vs SPA 차이

구분MPA (Multi Page Application)SPA (Single Page Application)
페이지 이동 방식매번 새로운 HTML을 요청최초 한 번만 HTML을 로드, 이후엔 JavaScript로 변경
속도서버에서 매번 새 HTML 제공 → 느림필요한 데이터만 갱신 → 빠름
사용성화면 깜빡임(플리커 현상), 새로고침 발생부드러운 전환, 앱 같은 UX
예시네이버, 다음, 일반 쇼핑몰Gmail, Facebook, Trello

2) SPA 동작 방식

  • 최초에 index.html 한 개만 다운로드됨.

  • 이후 페이지 이동 시 필요한 데이터만 받아와서 화면을 변경함.

  • 백엔드와 API 통신하여 필요한 데이터만 가져옴 (REST API, GraphQL 사용).

📌 MPA는 서버가 매번 HTML을 보내지만, SPA는 처음에 한 번만 HTML을 받고 이후에는 JavaScript가 화면을 변경한다.


3) SPA 구현하는 방법

React는 기본적으로 SPA 방식으로 동작한다.
React Router를 사용하면 페이지처럼 보이지만 실제로는 한 개의 HTML에서 컴포넌트만 바뀌는 것이다.

import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";

function Home() {
    return <h1>홈 페이지</h1>;
}

function About() {
    return <h1>소개 페이지</h1>;
}

function App() {
    return (
        <Router>
            <nav>
                <Link to="/"></Link> | <Link to="/about">소개</Link>
            </nav>
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/about" element={<About />} />
            </Routes>
        </Router>
    );
}

Link를 클릭하면 페이지 새로고침 없이 화면만 변경됨
Routes 안에 Route를 설정하여 컴포넌트만 교체


4) SPA의 장점 & 단점

a. SPA 장점

✔ 빠른 페이지 전환: 필요한 데이터만 받아오므로 속도가 빠름
✔ 앱 같은 UX: 새로고침 없이 자연스럽게 화면이 변경됨
✔ 백엔드와 분리 가능: REST API, GraphQL을 사용해 데이터를 주고받음

b. SPA 단점

⚠ 초기 로딩 속도 느림: 처음에 JS 파일을 다 받아야 해서 로딩이 길어질 수 있음
⚠ SEO(검색 엔진 최적화) 어려움: 검색 엔진이 초기 HTML만 읽어서 문제 발생
⚠ JS 의존도가 높음: JavaScript가 정상적으로 실행되지 않으면 화면이 안 나올 수도 있음

➡ 해결 방법으로 서버 사이드 렌더링(SSR), 정적 사이트 생성(SSG) 을 사용하기도 한다.



3. React 상태 끌어올리기(Lifting State Up)

여러 자식 컴포넌트가 동일한 데이터를 공유해야 할 때, 그 데이터를 공통 부모 컴포넌트로 올려서 상태를 관리하는 방식상태 끌어올리기(Lifting State Up) 라고 한다.

📌 왜 끌어올리는가?

  • 자식 컴포넌트 간에 상태를 공유하거나 동기화해야 할 때

  • 같은 데이터를 여러 자식이 쓰거나 수정해야 할 때

  • 단방향 데이터 흐름을 유지하면서 컴포넌트 간 데이터 일치를 위해 사용한다

1) 구성 흐름

자식 컴포넌트 A, B가 있음
➡ 두 컴포넌트가 공통 상태를 필요로 함
➡ 그 상태를 공통 부모 컴포넌트로 끌어올림
➡ 부모가 state를 관리하고, A와 B에 props로 내려줌
➡ A나 B에서 상태 변경 시, 부모의 상태를 바꾸는 함수도 props로 전달함

항목설명
상태 위치자식 → 부모로 끌어올림
props 역할상태값 전달 및 상태 변경 함수 전달
장점데이터 일관성 유지, 컴포넌트 재사용성 증가
사용 시기형제 컴포넌트 간 데이터 공유가 필요할 때

💡 비유를 하자면,
상태 끌어올리기는 마치 형제 둘이 싸우지 않게 부모가 직접 장난감을 관리하는 것과 같다고 보면 된다.
부모가 장난감(상태)을 가지고 있고,두 형제(자식 컴포넌트)가 부모한테 빌려서 쓰는 방식이다.

코드 구조

function Parent() {
  const [text, setText] = useState("");

  const handleChange = (value) => {
    setText(value);
  };

  return (
    <>
      <ChildA onChange={handleChange} />
      <ChildB value={text} />
    </>
  );
}

function ChildA({ onChange }) {
  return (
    <input
      onChange={(e) => onChange(e.target.value)}
      placeholder="입력하세요"
    />
  );
}

function ChildB({ value }) {
  return <p>입력된 값: {value}</p>;
}

흐름 요약

컴포넌트역할
Parent상태 text를 가지고 있고, 값을 변경하는 handleChange 함수도 가짐
ChildA사용자의 입력을 onChange를 통해 부모에게 전달함
ChildB부모로부터 전달받은 value를 화면에 출력함

📌 핵심 포인트

  • ChildAParent : 데이터 전달 (onChange 함수 호출)

  • ParentChildB : 데이터 전달 (props로 value 전달)

  • 상태는 오직 Parent에서만 관리함



4. React 상태 변경(State Update)

React 컴포넌트 내에서 변경 가능한 데이터(동적인 값)를 의미하며, 변경되면 해당 컴포넌트는 자동으로 다시 렌더링 된다.

⚠ 주의

  • 상태 변경 함수를 사용해야 함
  • 새로운 상태 값이 기존 상태 값과 달라야 함 === React의 불변성을 지켜야 함

📌 자바스크립트의 자료형

1. 기본형=원시형(Primitive Type)
불변(immutable)하는 단순한 데이터 변수에 값 자체를 저장

자료형설명예시
string문자열"안녕하세요", 'Hello'
number숫자 (정수, 실수 모두 포함)10, 3.14
boolean참 / 거짓true, false
null"없음"이라는 의도적 값null
undefined값이 아직 정의되지 않음undefined
symbol고유한 식별자 생성용Symbol('id')
bigint매우 큰 정수123n

2. 참조형(Reference Type)
값이 아닌 가변하는 복잡한 데이터, 메모리 주소(참조)를 저장하며, 복사하거나 비교할 때 주의가 필요하다.

자료형설명예시
object여러 값을 하나로 묶음{ name: '홍길동', age: 20 }
array순서 있는 값의 집합[1, 2, 3]
function실행 가능한 코드 덩어리function () {}


1) 기존 상태 복사 후 가공하는 방식

이유설명
불변성 유지React가 상태 변경 여부를 쉽게 감지할 수 있음
예측 가능성원본 상태를 유지하므로 버그 발생 위험 줄어듬
최적 렌더링불필요한 렌더링 방지 가능 (메모이제이션 등과 연계)

a. 스프레드 문법(Spread Syntax)

객체 상태에서 Spread 사용

const [user, setUser] = useState({ name: "홍길동", age: 20 });

const updateAge = () => {
  setUser({
    ...user,          // 기존 상태 복사
    age: user.age + 1 // 변경할 속성만 덮어쓰기
  });
};
  • ...user : 기존 객체 상태 복사
  • age: user.age + 1 : 변경할 속성만 덮어씀
  • 나머지 속성(name 등)은 그대로 유지됨

배열 상태에서 Spread 사용

값 추가 시

const [list, setList] = useState(["사과", "배"]);

const addItem = () => {
  setList([...list, "바나나"]); // 기존 배열 복사 + 새 요소 추가
};

값 삭제 시 (예: "배" 삭제)

const removeItem = () => {
  setList(list.filter(item => item !== "배")); // 필터링된 새 배열 생성
};

값 수정 시 (예: 특정 값 바꾸기)

const [nums, setNums] = useState([1, 2, 3]);

const updateItem = () => {
  setNums(nums.map(n => (n === 2 ? 20 : n))); // 조건 만족 시 값 변경
};

상황예시
객체 복사 후 변경{ ...obj, key: newValue }
배열 복사 후 추가[...arr, newItem]
배열 복사 후 삭제arr.filter()
배열 복사 후 수정arr.map() + { ...item, key: new }

b. Array.slice()

  • 기존 배열을 얕게 복사하는 메서드
  • 원본 배열은 변경하지 않으며, 복사한 새 배열을 반환
  • 주로 불변성 유지가 필요한 React 상태 관리에서 사용

기본 문법

const newArr = oldArr.slice();
  • slice() → 배열 전체 복사
  • slice(start, end) → 특정 구간 복사 (end는 미포함)

React에서의 사용 예시

배열 복사 후 요소 추가

const [items, setItems] = useState(["A", "B", "C"]);

const addItem = () => {
  const copy = items.slice();     // 배열 복사
  copy.push("D");                 // 복사본에 항목 추가
  setItems(copy);                 // 새로운 배열로 상태 변경
};

배열 복사 후 요소 삭제

const removeLast = () => {
  const copy = items.slice();     // 복사
  copy.pop();                     // 마지막 요소 제거
  setItems(copy);                 // 상태 업데이트
};

배열 복사 후 특정 위치의 값 변경

const updateIndex = (index, newValue) => {
  const copy = items.slice();     // 복사
  copy[index] = newValue;         // 특정 인덱스 값 변경
  setItems(copy);                 // 상태 업데이트
};

c. Object.assign()

  • 하나 이상의 객체를 복사/병합할 수 있는 내장 메서드
  • 첫 번째 인자로 복사 대상 객체(빈 객체 권장)를 넘기고, 이후 인자로 병합할 객체들을 나열한다.
Object.assign(복사본, 원본1, 원본2, ...)

React 상태 변경에서의 기본 사용 방식

const [user, setUser] = useState({ name: "홍길동", age: 20 });

const updateAge = () => {
  const newUser = Object.assign({}, user, { age: 21 }); // 복사 + age만 변경
  setUser(newUser);
};
  • Object.assign({}, user)user의 복사본 생성
  • { age: 21 } → 변경할 속성 추가 (기존 값 덮어씀)
  • 최종적으로 새 객체로 상태 업데이트

Object.assign 사용 시 주의점

항목설명
얕은 복사중첩 객체는 복사되지 않고 참조됨 ❗
배열에는 비추천배열 복사나 조작에는 slice, map, spread 사용 권장
스프레드보다 장황함요즘은 ...이 더 많이 쓰임

2) 새로운 배열을 리턴하는 고차 함수 메서드를 사용하는 방식

기존 배열을 변경하지 않고, 새 배열을 반환하는 메서드, 주로 React에서 불변성을 유지하며 상태를 변경할 때 사용한다.

a. Array.map()

기본 문법

const newArray = oldArray.map((item, index) => {
  return 가공된_값;
});
  • item : 현재 순회 중인 요소
  • index : 해당 요소의 인덱스
  • return 값이 새로운 배열의 요소가 된다

React에서의 사용 예시

const [fruits, setFruits] = useState(["사과", "배", "바나나"]);

특정 값 변경

const updateFruit = () => {
  const updated = fruits.map(fruit =>
    fruit === "배" ? "복숭아" : fruit
  );
  setFruits(updated);
};
  • "배""복숭아"로 바꿈
  • 나머지는 그대로 복사됨
  • 원본 fruits는 변경되지 않음

배열 안 객체의 특정 항목 수정

const [users, setUsers] = useState([
  { id: 1, name: "철수" },
  { id: 2, name: "영희" }
]);

const updateName = () => {
  const updated = users.map(user =>
    user.id === 2 ? { ...user, name: "수정된 영희" } : user
  );
  setUsers(updated);
};
  • user.id === 2일 때 name만 변경
  • 객체는 ...user로 복사하여 불변성 유지

인덱스를 활용한 가공

const addIndex = () => {
  const updated = fruits.map((fruit, index) => `${index + 1}. ${fruit}`);
  setFruits(updated);
};

➡️ 결과: ["1. 사과", "2. 배", "3. 바나나"]


Array.map 사용 시 주의점

항목설명
원본 유지map()은 원본 배열을 변경하지 않음
항상 return 필요리턴하지 않으면 undefined로 채워짐
불변성 필수객체를 다룰 땐 ...로 복사할 것

b. Array.filter()

배열에서 조건을 만족하는 요소만 걸러내어 새로운 배열을 생성하는 고차 함수 메서드

기본 문법

const newArray = oldArray.filter((item, index) => {
  return 조건식;
});
  • 조건식이 true인 요소만 새 배열에 포함
  • false인 요소는 제외

React에서의 사용 예시

const [fruits, setFruits] = useState(["사과", "배", "바나나"]);

특정 항목 제거

const removeFruit = () => {
  const updated = fruits.filter(fruit => fruit !== "배");
  setFruits(updated);
};
  • "배"를 제외한 나머지만 남김
  • 새로운 배열로 상태 변경
  • 원본 배열은 건드리지 않음

배열 안 객체 조건 필터링

const [users, setUsers] = useState([
  { id: 1, name: "철수" },
  { id: 2, name: "영희" },
  { id: 3, name: "짱구" }
]);

const removeUser = () => {
  const updated = users.filter(user => user.id !== 2);
  setUsers(updated);
};
  • id === 2인 영희를 제거
  • 나머지 객체는 유지

조건 만족 요소만 남기기

const [numbers, setNumbers] = useState([1, 2, 3, 4, 5]);

const keepEven = () => {
  const updated = numbers.filter(n => n % 2 === 0);
  setNumbers(updated);
};

➡️ 결과: [2, 4] 짝수만 남겨 새로운 배열로 상태 변경


요약 하면

항목설명
용도필터링 / 삭제
원본 배열변경 없음
반환값새 배열
조건식true면 포함, false면 제외됨


5. Rendering Elements

1) 엘리먼트(Element)

React 엘리먼트는 UI를 화면에 표현하기 위한 가장 작은 단위로, React 애플리케이션의 빌딩 블록이다.

특징설명
불변성한 번 생성된 엘리먼트는 수정되지 않음. 업데이트 시 새로 생성.
React.createElementJSX는 결국 React.createElement() 함수로 변환됨.
Plain Object엘리먼트는 자바스크립트 객체일 뿐이며, 실제 DOM은 아님.
UI의 스냅샷현재 시점의 UI 상태를 묘사하는 "스냅샷"이라고 볼 수 있음.

2) React 엘리먼트 vs DOM 엘리먼트

구분🧩 React 엘리먼트🧱 DOM 엘리먼트
정의React가 화면을 그리기 위해 내부적으로 사용하는 자바스크립트 객체브라우저가 실제로 렌더링하는 HTML 요소(노드)
생성 방식React.createElement() 또는 JSX (<h1>Hello</h1>)document.createElement() 또는 HTML (<h1>Hello</h1>)
목적UI 상태를 설명하는 “스냅샷”을 표현실제 브라우저에 표시되는 실체
예시{ type: 'h1', props: { children: 'Hello' } }<h1>Hello</h1> 브라우저 화면에 실제 표시되는 요소
변경 처리React가 가상 DOM과 비교 후 필요한 부분만 실제 DOM에 반영직접 수정해야 하며, 변경 시 전체 DOM이 영향을 받기 쉬움
불변성불변 (immutable) → 새로운 요소를 만들어 교체변경 가능 (mutable) → 속성이나 텍스트를 직접 수정 가능

React 엘리먼트는 UI를 기술하는 설명서이고, DOM 엘리먼트는 그 설명서를 바탕으로 실제 브라우저에 그려지는 실체입니다.

React 엘리먼트 → DOM 엘리먼트 렌더링 흐름

1. JSX 작성
------------------------
const element = <h1>Hello, React!</h1>;

      ↓

2. JSX는 컴파일됨
------------------------
React.createElement('h1', null, 'Hello, React!');

      ↓

3. React 엘리먼트 (Plain Object)
------------------------
{
  type: 'h1',
  props: {
    children: 'Hello, React!'
  }
}

      ↓

4. ReactDOM이 렌더링 시작
------------------------
ReactDOM.createRoot(root).render(element);

      ↓

5. 가상 DOM에 적용
------------------------
- React는 위 엘리먼트를 Virtual DOM(가상 DOM)에 먼저 생성
- 이전 가상 DOM과 비교 (diffing)

      ↓

6. 변경된 부분만 실제 DOM에 반영 (DOM 업데이트)
------------------------
- 최소한의 DOM 조작 발생
- 실제 브라우저에 `<h1>Hello, React!</h1>` 그려짐 ✅


6. CSR vs SSR

1) CSR(Client-Side Rendering)

HTML/CSS/JS를 먼저 브라우저에 보내고, JavaScript가 실행되면서 화면이 렌더링된다.

대표 프레임워크 : React (기본), Vue 등

a. 장단점

장점단점
사용자 경험이 부드러움 (한 번 로딩되면 빠름)초기 로딩이 느릴 수 있음
클라이언트에서 상태 관리가 쉬움SEO(검색엔진 최적화)에 불리함

2) SSR(Server-Side Rendering)

HTML을 서버에서 미리 렌더링해서 브라우저에 전달 → 바로 화면에 표시된다.

대표 프레임워크 : Next.js (React 기반), Nuxt.js (Vue 기반)

a. 장단점

장점단점
초기 렌더링 속도 빠름 (특히 느린 기기에서)서버 부담 증가
SEO에 유리함인터랙티브한 페이지는 추가 JS 실행이 필요함

3) CSR과 SSR의 차이점

구분CSR (클라이언트 사이드 렌더링)SSR (서버 사이드 렌더링)
렌더링위치 브라우저(클라이언트)서버
초기 로딩 속도느릴 수 있음빠름
사용자 경험 (UX)한 번 로딩 후 빠르고 부드러움새로고침마다 서버 요청
SEO (검색엔진 최적화)불리함 (JS 실행 필요)유리함 (HTML 바로 제공)
서버 부하낮음 (클라이언트에서 처리)높음 (매 요청마다 렌더링)
적합한 경우앱 중심, 로그인 기반 서비스 (예: 대시보드)콘텐츠 중심, 공개 페이지 (예: 블로그, 쇼핑몰)


끝맺음.

이런이런...오늘 강의가 왜 이렇게 많은가 했더니..
내가 앞서 나가고 있었음..ㅠㅠ
그래도 예습했다고 생각하고 화이팅!!
Element 내용이 부족해서 추가하였음

profile
UI/UX디자이너의 코딩 공부

2개의 댓글

comment-user-thumbnail
2025년 4월 10일

설명 깔끔합니다!

1개의 답글