리액트 애플리케이션을 개발할 때 가장 많이 접하게 되는 단어는 단연 ‘상태(State)’이다. 리액트가 왜 상태를 그토록 강조하는지, 그리고 데이터를 다루는 두 가지 핵심 도구인 Props와 State가 어떻게 다른지 상세히 정리해 본다.

1. 리액트에서 ‘상태(State)’란 무엇인가?
상태를 아주 간단하게 정의하자면, “어느 한 시점에 프로그램이 사용할 수 있는 모든 정보”라고 할 수 있다.
우리가 일상적으로 사용하는 소셜 미디어 앱을 생각해 보자. 수많은 사용자가 실시간으로 데이터를 주고받으며, 화면에 보이는 정보는 끊임없이 변한다. 이때 시스템이 특정 순간에 참조하고 있는 모든 정보의 집합을 ‘스냅샷(Snapshot)’이라고 부르며, 이것이 곧 프로그램의 상태가 된다.
상태 변화의 예시
프로그램이 실행되는 동안 상태는 끊임없이 변화한다. 하나의 문자열을 여러 문자로 나누어 출력하는 과정을 예로 들어 본다.
-
초기 상태: 단일 문자열 변수만 존재한다.
-
변화 중: 문자열을 나누어 배열로 저장하면, 프로그램이 참조할 수 있는 정보(배열 원소)가 늘어난다.
-
최종 상태: 배열의 각 원소를 하나씩 출력하는 과정에서 프로그램이 다루는 정보는 시간에 따라 계속 변하게 된다.
이처럼 시간의 흐름에 따라 변화하며 애플리케이션의 동작을 결정하는 데이터를 효율적으로 관리하는 것이 리액트 개발의 본질이다.
2. 가변(Mutable) 상태와 불변(Immutable) 상태
리액트에서 데이터를 다루는 철학은 크게 가변성(Mutability)과 불변성(Immutability)으로 나뉜다. 이 차이를 아는 것이 리액트의 렌더링 원리를 파악하는 첫걸음이다.
가변(Mutable) 상태
-
정의: 데이터를 직접 덮어쓸 수 있는 상태이다.
-
특징: 새로운 데이터가 들어오면 기존 데이터는 사라지고 새로운 값으로 교체된다. 마치 원본 파일을 계속해서 ‘덮어쓰기’ 하는 것과 같다. 리액트 컴포넌트 내부에서 변경 가능한 데이터인 상태(State)는 개념적으로 가변적이다.
불변(Immutable) 상태
-
정의: 한 번 생성되면 그 자체를 변경하지 않는 상태이다.
-
특징: 데이터가 변경되어야 할 때 기존 데이터를 수정하는 것이 아니라, 변경 사항이 반영된 새로운 복사본을 만든다. 이는 ‘다른 이름으로 저장’ 기능과 유사하며, 이전 데이터를 유지할 수 있다는 장점이 있다. 리액트의 속성(Props)은 읽기 전용으로, 불변성을 엄격히 유지해야 한다.
3. 리액트가 데이터를 다루는 두 가지 도구: Props와 State
현대 웹 브라우저의 UI는 서버 데이터, 레이아웃, 자바스크립트 로직 등이 복잡하게 얽혀 있다. 리액트는 이러한 복잡성을 관리하기 위해 두 가지 데이터 관리 API를 제공한다.
-
상태(State): 컴포넌트 내부에서 스스로 관리하며, 필요에 따라 수시로 변경 가능한(Mutable) 데이터이다.
-
속성(Props): 부모 컴포넌트로부터 전달받으며, 컴포넌트 내에서는 절대로 변경할 수 없는(Immutable) 읽기 전용 데이터이다.
[Image comparing React State and Props data flow and ownership]
리액트 애플리케이션 내에서 데이터가 어떻게 흐르는지 이해하는 것은 실무에서 매우 중요하다. 특히 리액트는 **단방향 데이터 흐름(One-way Data Flow)**의 원칙을 따르기 때문에, 데이터가 어디서 시작되어 어디로 전달되는지 명확히 파악해야 버그를 최소화할 수 있다.
리액트의 상태 개념은 처음에는 단순해 보이지만, 애플리케이션이 복잡해질수록 이를 효율적으로 설계하는 것이 가장 큰 과제가 된다. 하지만 “상태는 특정 시점의 정보 묶음”이며, 리액트가 Props와 State를 통해 이 정보를 관리한다는 기본 원리만 기억한다면 복잡한 UI도 충분히 제어할 수 있다. 상태를 장악하는 자가 리액트 애플리케이션의 흐름을 지배하게 된다.