Type something to search...

6강. State 관리

1. State 관리

1.1. State란?

State는 컴포넌트의 데이터 저장소다. 값이 변경되면 화면이 자동으로 다시 그려진다.

1.1.1. 기본 사용법

import { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return (
<div>
<p>횟수: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}

1.2. useState 동작 원리

useState는 두 개의 값을 배열로 반환한다.

  • 첫 번째: 현재 상태 값
  • 두 번째: 상태를 변경하는 함수
const [value, setValue] = useState(초기값);

1.2.1. 예제 1: 카운터

function Counter() {
const [num, setNum] = useState(0);
const plus = () => setNum(num + 1);
const minus = () => setNum(num - 1);
return (
<div>
<h2>{num}</h2>
<button onClick={plus}>+</button>
<button onClick={minus}>-</button>
</div>
);
}

1.3. 객체와 배열 State 관리

1.3.1. 객체 수정하기

주의

주의: 직접 수정 금지!

상태 객체나 배열을 직접 수정하면 안 된다. 반드시 새로운 객체/배열을 만들어야 한다.

const [user, setUser] = useState({ name: '철수', age: 20 });
// ✅ 올바른 방법: 전개 연산자(...) 사용
setUser({ ...user, name: '영희' });

전개 연산자(...)란?

...은 객체나 배열의 내용물을 꺼내서 펼치는 문법이다.

// 원본 객체
const user = { name: '철수', age: 20 };
// ...user는 name: '철수', age: 20을 꺼내서 펼친다
const newUser = { ...user, name: '영희' };
// 결과: { name: '영희', age: 20 }
// → 펼친 뒤 같은 키(name)를 덮어쓴다

배열도 같은 원리다:

const fruits = ['사과', '바나나'];
const newFruits = [...fruits, '오렌지'];
// 결과: ['사과', '바나나', '오렌지']
// → 기존 항목을 펼치고 새 항목을 추가한다

1.3.2. 배열 수정하기

const [items, setItems] = useState(['사과', '바나나']);
// ✅ 항목 추가
setItems([...items, '오렌지']);
// ✅ 항목 삭제 (filter 사용)
setItems(items.filter((item, index) => index !== 0));

1.4. useEffect란?

useEffect는 컴포넌트가 화면에 나타날 때, 사라질 때, 또는 특정 값이 변할 때 실행할 코드를 정의한다.

1.4.1. 기본 사용법

import { useEffect } from 'react';
useEffect(() => {
console.log('화면이 나타남 (Mount)');
return () => {
console.log('화면에서 사라짐 (Unmount)');
};
}, []); // 빈 배열: 처음 한 번만 실행

1.4.2. 의존성 배열

  • []: 처음 한 번만 실행
  • [count]: count 값이 변할 때마다 실행
  • 생략: 매번 렌더링될 때마다 실행

1.5. 실습: 간단한 Todo 앱

useState와 useEffect를 함께 활용하는 예제이다.

import { useState, useEffect } from 'react';