개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

State — 컴포넌트 내부의 변경 가능한 데이터

2026년 4월 28일
ReactStateuseState

State란 무엇인가

State는 컴포넌트 내부에서 관리하는 변경 가능한 데이터입니다. State가 바뀌면 React는 해당 컴포넌트를 다시 렌더링하여 UI를 최신 상태로 갱신합니다.

사용자 입력, 서버 응답, 타이머 등 시간이 지나면서 변하는 데이터는 State로 관리합니다.

useState 사용법

함수형 컴포넌트에서 State를 사용하려면 useState Hook을 사용합니다.

import { useState } from 'react';

function Counter() {
  // [현재값, 변경함수] = useState(초기값)
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>현재 값: {count}</p>
      <button onClick={() => setCount(count + 1)}>증가</button>
      <button onClick={() => setCount(count - 1)}>감소</button>
    </div>
  );
}

useState는 두 개의 요소를 가진 배열을 반환합니다. 첫 번째는 현재 상태 값이고, 두 번째는 상태를 변경하는 함수입니다. 배열 구조 분해를 활용하여 이름을 자유롭게 지정할 수 있습니다.

초기값으로 함수를 전달하면 컴포넌트가 처음 마운트될 때만 실행됩니다. 계산 비용이 큰 초기값을 설정할 때 유용합니다.

// 매 렌더링마다 실행됨 (비효율)
const [data, setData] = useState(expensiveComputation());

// 최초 마운트 시에만 실행됨 (효율적)
const [data, setData] = useState(() => expensiveComputation());

불변 업데이트

State는 직접 수정해서는 안 됩니다. 반드시 setState 함수를 통해 새 값을 반환해야 합니다. 이를 불변 업데이트(Immutable Update)라고 합니다.

// 금지: state를 직접 수정
const [user, setUser] = useState({ name: '홍길동', age: 30 });
user.age = 31; // React가 변경을 감지하지 못함

// 올바른 방법: 새 객체를 생성하여 전달
setUser({ ...user, age: 31 });

React가 변경을 감지하는 방법은 이전 참조와 새 참조를 비교(===)하는 것입니다. 객체를 직접 수정하면 참조가 바뀌지 않으므로 React는 변경이 없다고 판단하여 리렌더링이 발생하지 않습니다.

배열 State의 경우도 마찬가지입니다.

const [items, setItems] = useState([]);

// 금지
items.push(newItem);
setItems(items);

// 올바른 방법: 새 배열 생성
setItems([...items, newItem]);

// 항목 제거
setItems(items.filter(item => item.id !== targetId));

// 항목 수정
setItems(items.map(item =>
  item.id === targetId ? { ...item, done: true } : item
));

리렌더링 트리거 조건

setState 함수가 호출되면 React는 다음 두 조건을 확인합니다.

  1. 새 값이 이전 값과 같은가? (Object.is로 비교)
  2. 같다면 리렌더링을 건너뜁니다.
const [count, setCount] = useState(0);

// count가 이미 0이면 리렌더링 발생 안 함
setCount(0);

// 객체는 참조가 다르면 항상 리렌더링 발생
setUser({ ...user }); // 내용이 같아도 새 객체이므로 리렌더링 발생

여러 State 업데이트가 동일한 이벤트 핸들러 안에서 발생하면 React는 이를 일괄 처리(Batching)하여 렌더링을 한 번만 수행합니다.

function handleClick() {
  setCount(c => c + 1);
  setName('홍길동');
  // 위 두 업데이트는 하나의 리렌더링으로 처리됨
}

Props와 State의 차이

구분PropsState
소유자부모 컴포넌트해당 컴포넌트
변경 가능 여부읽기 전용변경 가능
변경 주체부모해당 컴포넌트
용도외부에서 데이터 주입내부 동적 데이터 관리

어떤 데이터를 State로 관리해야 할지 판단할 때는 다음 질문을 해봅니다. "이 데이터가 변하는가? 변했을 때 UI가 달라지는가?" 두 질문 모두 "예"라면 State가 적합합니다.

정리

State는 컴포넌트를 동적으로 만드는 핵심 메커니즘입니다. useState로 선언하고, 반드시 setState 함수를 통해 업데이트해야 합니다. 불변 업데이트 원칙을 지켜야 React가 변경을 정확히 감지하고 리렌더링을 올바르게 수행합니다.

← 이전 글Props — 부모가 자식에게 전달하는 데이터
다음 글 →Event Handling — React에서 사용자 이벤트를 처리하는 방식