props와 state의 차이, 명확한 역할 분담

572025년 10월 11일3

propsstate.
리액트 컴포넌트를 움직이는 두 개의 심장이 마침내 모습을 드러냈지만, 팀 내부에서는 여전히 두 개념의 경계에 대한 혼란이 남아있었다. 언제 props를 쓰고, 언제 state를 써야 하는가? 이 질문에 대한 명확한 가이드라인이 필요했다.

"둘 다 결국 데이터를 담는 객체인데, 왜 굳이 두 개로 나눠야 하는 거죠?"
새로운 팀원 중 한 명이 근본적인 질문을 던졌다. "그냥 하나의 데이터 객체로 합쳐서 관리하면 더 단순하지 않을까요?"

그의 질문은 일리가 있었다. 하지만 조던 워크는 고개를 저었다.
"그 둘을 분리하는 것이야말로 리액트가 복잡성을 관리하는 핵심적인 방법입니다. 데이터의 ‘소유권(Ownership)’을 명확히 하기 위해서죠."

그는 화이트보드에 두 개의 열을 만들고, propsstate의 본질적인 차이를 적어 내려갔다.

특징 props (Properties) state (State)
소유권 부모 컴포넌트가 소유하고 결정한다. 컴포넌트 자신이 소유하고 관리한다. (완전히 비공개)
데이터 흐름 위에서 아래로, 단방향으로만 흐른다. 컴포넌트 내부에 완전히 갇혀있다(캡슐화).
변경 가능성 절대 변경할 수 없다 (자식에게는 읽기 전용). 특별한 메서드를 통해서만 변경할 수 있다.
목적 컴포넌트의 설정과 초기 데이터를 전달하는 용도. 사용자의 상호작용 등, 시간에 따라 변하는 값을 저장하는 용도.
비유 함수의 인자(Arguments) 함수 내의 지역 변수(Local Variables)

이 표는 모든 것을 명확하게 보여주었다. propsstate는 단순히 데이터를 담는 통이 아니었다. 그들은 데이터의 출처와 생명주기를 규정하는, 완전히 다른 목적을 가진 시스템이었다.

조던은 CommentBox 컴포넌트를 다시 예로 들었다.
"생각해 봅시다. CommentBox가 렌더링될 때, 현재 로그인한 사용자의 아바타 이미지는 누가 결정해야 할까요?"

"그건 CommentBox의 부모인 <Post> 컴포넌트가 알고 있겠죠." 맷이 대답했다.

"맞습니다. 그렇기 때문에 currentUserAvatarUrlprops로 받아야 합니다. CommentBox는 자신의 아바타가 누구의 것인지 스스로 결정할 권한도, 이유도 없으니까요. 이건 명백히 부모의 소관입니다."

"그럼, 사용자가 입력하고 있는 댓글 텍스트는 누가 소유해야 할까요?"

이번에는 크리스가 대답했다.
"그건 전적으로 <CommentBox> 내부의 일입니다. 부모인 <Post>는 사용자가 '안'이라고 썼다가 '안녕하세요'라고 바꾸는 그 중간 과정을 전혀 알 필요가 없죠. 오직 최종적으로 '게시' 버튼을 눌렀을 때의 결과만 알면 됩니다."

"정확합니다. 그래서 commentTextstate로 관리되어야 합니다. 그 값은 <CommentBox>의 완전한 내부 정보이며, 외부에서는 그 존재조차 알 필요가 없는, 완벽하게 캡슐화된 데이터입니다."

이 명확한 역할 분담은 개발자들에게 강력한 사고의 틀을 제공했다. 어떤 데이터를 마주했을 때, 그들은 이제 단 하나의 질문만 던지면 되었다.

"이 데이터의 소유권은 누구에게 있는가?"

만약 데이터가 부모로부터 와야 한다면, 그것은 props다.
만약 데이터가 컴포넌트 스스로의 상호작용에 의해 생성되고 변경되어야 한다면, 그것은 state다.

이 단순한 질문 하나가 수많은 설계상의 고민을 해결해주었다. propsstate라는 두 개의 축은 리액트 애플리케이션의 데이터 흐름을 튼튼하게 지탱하는 기둥이 될 터였다.

이제 소유권의 문제는 해결되었다. 팀의 시선은 마침내 마지막 남은 미스터리, 즉 state를 변경하는 '특별한 메서드'의 정체로 향했다. 그 메서드의 이름 속에 리액트의 모든 마법이 응축되어 있었다.