BioPlayground

🧬
목록으로

useState — React 상태 관리의 시작

React useState의 동작 원리, 상태 업데이트 규칙, 그리고 흔한 실수를 설명합니다.

입문
|
5
|
검증 완료 (2026-07)
진행률0/55 (0%)

useState — React 상태 관리의 시작

이 토픽을 마치면

useState로 상태를 만들고 업데이트하는 방법, 그리고 리렌더링이 일어나는 원리를 이해하게 됩니다.


일반 변수로는 안 됩니다

javascript
function Counter() {
  let count = 0;

  function handleClick() {
    count += 1;
    console.log(count); // 1, 2, 3... 올라감
  }

  return <button onClick={handleClick}>{count}</button>;
  // 화면에는 항상 0
}

count는 올라가지만 화면은 바뀌지 않습니다. React는 일반 변수가 바뀌는 걸 감지하지 못합니다. 화면을 업데이트하려면 React에게 "상태가 바뀌었다"고 알려줘야 합니다.


useState

javascript
import { useState } from "react";

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

  return (
    <button onClick={() => setCount(count + 1)}>
      {count}
    </button>
  );
}

useState(0)은 두 가지를 반환합니다:

  • count: 현재 상태 값
  • setCount: 상태를 변경하는 함수

setCount를 호출하면 React가 컴포넌트를 리렌더링합니다. 새로운 count 값으로 화면이 다시 그려집니다.


상태 업데이트는 비동기입니다

javascript
function handleClick() {
  setCount(count + 1);
  console.log(count); // 아직 이전 값!
}

setCount를 호출해도 count가 즉시 바뀌지 않습니다. 다음 렌더링에서 새 값이 반영됩니다.

이전 값을 기반으로 업데이트할 때는 함수형 업데이트를 씁니다:

javascript
setCount(prev => prev + 1);

prev에 현재 최신 값이 들어옵니다. 여러 번 연속 호출해도 정확합니다:

javascript
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);
// count가 3 증가

객체와 배열 상태

javascript
const [user, setUser] = useState({ name: "Alice", age: 25 });

// 나쁜 예: 직접 수정
user.age = 26; // React가 변화를 감지 못함
setUser(user); // 같은 참조라 리렌더링 안 됨

// 좋은 예: 새 객체 생성
setUser({ ...user, age: 26 });

React는 참조가 바뀌었는지를 확인합니다. 기존 객체를 수정하면 참조가 같아서 변화를 감지하지 못합니다. Spread 연산자로 새 객체를 만들어야 합니다.

배열도 마찬가지입니다:

javascript
const [items, setItems] = useState(["a", "b"]);

// 추가
setItems([...items, "c"]);

// 삭제
setItems(items.filter(item => item !== "b"));

// 수정
setItems(items.map(item => item === "a" ? "A" : item));

push, splice 같은 원본 변경 메서드는 쓰지 않습니다.


useState 여러 개

javascript
const [name, setName] = useState("");
const [age, setAge] = useState(0);
const [isActive, setIsActive] = useState(false);

관련 없는 상태는 따로 선언합니다. 항상 같이 바뀌는 값들은 하나의 객체로 묶을 수도 있습니다.


핵심

useState는 React 컴포넌트에 상태를 추가하고, setState 호출 시 리렌더링합니다. 상태 업데이트는 비동기이므로, 이전 값 기반 업데이트는 함수형(prev => ...)을 쓰세요. 객체/배열 상태는 원본을 수정하지 말고 새 것을 만들어야 합니다.