MMeshOps
AI가 놓치는 엣지 케이스까지: Next.js와 TypeScript 실전
6예상 10입문

레고 블록 조립하기: React 컴포넌트, Props, State

화면을 작은 부품(컴포넌트)으로 쪼개고, 부품 간에 데이터를 전달(Props)하며 기억(State)하는 원리를 배웁니다.

현대의 웹 페이지는 거대한 하나의 덩어리가 아니라, 작고 독립적인 여러 조각들이 모여 만들어집니다. 이번 시간에는 바이브코딩으로 React 프론트엔드 코드를 다룰 때 가장 빈번하게 마주치는 세 가지 핵심 개념인 컴포넌트(Component), 프롭스(Props), 그리고 상태(State)를 알아봅니다. 이 세 가지 요소는 화면을 그리고, 데이터를 주고받으며, 사용자의 행동을 기억하는 가장 근본적인 원리입니다.

화면을 구성하는 기본 단위, 컴포넌트

React로 만들어진 웹 애플리케이션을 보면, 수많은 버튼과 텍스트, 이미지들이 화면을 채우고 있습니다. 개발자들은 이 화면을 한 번에 통째로 만들지 않습니다. 대신 재사용이 가능한 작은 부품 단위로 쪼개어 개발하는데, 이를 컴포넌트(Component) 라고 부릅니다.

컴포넌트란 무엇인가

컴포넌트는 화면의 특정 부분을 나타내는 독립적인 코드 블록입니다. 쉽게 말해 우리가 화면에 보여주고 싶은 UI(사용자 인터페이스) 요소 하나하나를 정의해둔 설계도와 같습니다. 버튼 하나, 입력창 하나가 각각 컴포넌트가 될 수 있고, 이런 작은 컴포넌트들이 모여서 하나의 '로그인 폼 컴포넌트'를 이루기도 합니다.

자바스크립트 측면에서 컴포넌트는 사실 단순한 '함수'에 불과합니다. 단지 차이점이라면 이 함수가 숫자나 문자를 반환하는 것이 아니라, 화면에 그려질 HTML 구조를 반환한다는 것입니다. 바이브코딩을 하다 보면 AI가 자주 "이 부분은 별도의 컴포넌트로 분리했습니다"라고 말하는 것을 볼 수 있는데, 이는 코드를 더 관리하기 쉽게 쪼개어 두었다는 뜻입니다.

레고 블록처럼 조립하는 UI

컴포넌트를 이해하는 가장 좋은 비유는 레고 블록입니다. 레고 블록 하나하나를 조립해서 거대한 성이나 자동차를 만드는 것처럼, 우리는 작은 버튼 컴포넌트와 입력창 컴포넌트를 조립해서 완전한 웹 페이지를 만듭니다.

웹 페이지를 이루는 컴포넌트 구성

Header 컴포넌트
화면 상단의 로고와 네비게이션 메뉴를 담당합니다.
Sidebar 컴포넌트
화면 좌측의 카테고리나 부가 메뉴 목록을 보여줍니다.
Article 컴포넌트
본문 내용과 제목, 작성자 정보를 묶어서 표시합니다.
Button 컴포넌트
클릭할 수 있는 버튼 모양과 기본 동작을 정의하여 곳곳에서 재사용합니다.

이렇게 컴포넌트 기반으로 개발하면 재사용성이 크게 높아집니다. 예를 들어 '좋아요 버튼' 컴포넌트를 한 번만 잘 만들어 두면, 게시글 페이지, 댓글 영역, 프로필 페이지 등 화면의 어떤 곳에서든 동일하게 불러와서 사용할 수 있습니다. 코드를 중복해서 작성할 필요가 없고, 나중에 버튼 디자인을 바꿔야 할 때도 해당 컴포넌트 파일 하나만 수정하면 모든 화면에서 동시에 디자인이 변경됩니다.

데이터를 전달하는 방법, Props

우리가 컴포넌트를 재사용할 때, 항상 완전히 똑같은 내용만 보여주는 것은 아닙니다. 예를 들어, 사용자 프로필을 보여주는 컴포넌트가 있다고 가정해 봅시다. 이 컴포넌트는 화면 구성은 동일하지만 사용자 이름과 아바타 이미지는 매번 다르게 나타나야 합니다.

Props의 개념과 역할

이렇게 재사용되는 컴포넌트에 매번 다른 데이터를 전달하기 위해 사용하는 것이 바로 Props(Properties의 줄임말) 입니다. Props는 쉽게 말해 부모 컴포넌트가 자식 컴포넌트에게 전달해주는 '설정 값'이자 '데이터 꾸러미'입니다.

함수에 매개변수(인자)를 넣어서 실행하는 원리와 정확히 같습니다. `UserProfile`이라는 컴포넌트 함수를 호출할 때 `name="홍길동"`이라는 Props를 전달하면, 그 컴포넌트는 전달받은 이름을 화면에 렌더링합니다.

부모에서 자식으로 흐르는 데이터

React의 데이터 흐름은 명확한 규칙을 가집니다. 데이터는 항상 상위 컴포넌트(부모)에서 하위 컴포넌트(자식) 방향으로만 흐릅니다. 이를 단방향 데이터 흐름이라고 합니다. 자식 컴포넌트는 부모가 건네준 Props를 읽기 전용으로만 사용할 수 있으며, 마음대로 그 값을 수정할 수 없습니다.

Props를 통한 데이터 전달의 예

버튼 컴포넌트를 생각해 보겠습니다.

// 부모 컴포넌트에서의 사용
<CustomButton text="저장하기" color="blue" />
<CustomButton text="삭제하기" color="red" />

위의 예시에서 `text`와 `color`가 바로 Props입니다. `CustomButton` 컴포넌트는 부모로부터 이 두 가지 정보를 받아, 하나는 파란색 저장 버튼으로, 다른 하나는 빨간색 삭제 버튼으로 변신하여 화면에 나타나게 됩니다.

컴포넌트의 기억력, State

Props가 외부에서 주어지는 데이터라면, 상태(State) 는 컴포넌트 스스로가 내부적으로 기억하고 관리하는 데이터입니다.

State가 필요한 이유

웹 페이지는 정적이지 않고 사용자와 계속 상호작용합니다. 사용자가 입력창에 글자를 치면 글자가 화면에 나타나야 하고, 좋아요 버튼을 누르면 하트 색깔이 붉게 변하면서 숫자가 올라가야 합니다. 이러한 상호작용에 따라 '변화하는 값'을 다루기 위해 State가 필요합니다.

컴포넌트는 화면에 렌더링된 이후에도 자신의 State 값을 계속 기억하고 있습니다. 만약 좋아요 버튼이 클릭되었다면, 그 버튼 컴포넌트는 내부의 State를 `isLiked = true`로 변경하여 자신이 클릭된 상태임을 스스로 저장합니다.

State 변경과 화면 업데이트

State가 가지는 가장 강력한 특징은, State의 값이 변경되면 React가 자동으로 해당 컴포넌트를 다시 화면에 그린다(Re-render) 는 점입니다.

State 변화에 따른 React의 동작 과정

사용자가 '좋아요' 버튼을 클릭

클릭 이벤트가 발생하여 컴포넌트 내부의 State 값을 변경합니다.

State 값이 업데이트됨

React가 State 변화를 감지하고, 해당 컴포넌트가 새로운 상태를 가졌음을 인지합니다.

화면 재렌더링(Re-render)

React가 변경된 State를 바탕으로 컴포넌트를 새로 그려서 빈 하트를 붉은 하트로 화면에 업데이트합니다.

과거의 전통적인 웹 개발에서는 데이터가 바뀌면 개발자가 직접 화면의 특정 요소(DOM)를 찾아서 그 안의 색상이나 텍스트를 하나하나 수정해 주어야 했습니다. 그러나 React에서는 단지 State라는 데이터 값만 바꿔주면, 화면은 AI처럼 알아서 새 데이터에 맞게 자신을 갱신합니다.

이러한 선언적 렌더링은 프론트엔드 개발의 난이도를 크게 낮춰주는 핵심 기술입니다. AI에게 코드를 수정해 달라고 할 때 "버튼을 누르면 글자가 바뀌게 해주세요"라고 요청하면, AI는 내부적으로 이 State를 추가하여 문제를 해결하게 됩니다.

개념 퀴즈

퀴즈 답을 맞춰야 학습 완료가 됩니다.

다음 중 React 컴포넌트에서 부모가 자식에게 데이터를 전달할 때 사용하는 방식은 무엇인가요?

3줄 요약

  1. 1컴포넌트(Component)는 화면을 구성하는 재사용 가능한 독립적인 UI 조각입니다.
  2. 2Props는 부모 컴포넌트가 자식에게 전달하는 읽기 전용 데이터입니다.
  3. 3State는 컴포넌트 내부에서 스스로 관리하며, 값이 변경되면 화면이 자동으로 업데이트됩니다.