컴포넌트란 무엇인가
React에서 컴포넌트는 UI를 구성하는 독립적인 조각이다. 레고 블록이라고 생각하면 쉽다. 버튼 하나, 헤더 하나, 카드 하나가 각각 컴포넌트가 될 수 있고, 이 블록들을 조합해서 전체 페이지를 만든다.
2026년 기준으로 함수형 컴포넌트가 표준이다. 클래스 컴포넌트는 레거시 프로젝트에서만 볼 수 있다. 함수 하나가 곧 컴포넌트이고, 그 함수가 반환하는 것이 화면에 보이는 UI다.
이게 전부다. 함수 이름이 컴포넌트 이름이 되고, return 뒤에 오는 JSX가 화면에 렌더링된다. 함수 이름은 반드시 대문자로 시작해야 한다. React가 HTML 태그와 커스텀 컴포넌트를 구분하는 기준이기 때문이다.
- 컴포넌트 = UI를 반환하는 JavaScript 함수
- 이름은 반드시 대문자로 시작 (PascalCase)
- 하나의 컴포넌트는 하나의 역할만 담당하는 것이 이상적
- 재사용 가능하게 설계하는 것이 핵심
JSX, HTML처럼 생긴 JavaScript
JSX는 JavaScript 안에서 HTML 같은 문법을 쓸 수 있게 해주는 확장 문법이다. 브라우저가 직접 이해하는 건 아니고, Babel 같은 도구가 일반 JavaScript로 변환해준다.
JSX를 쓰면 UI 구조를 직관적으로 파악할 수 있다. 다만 몇 가지 HTML과 다른 점이 있다.
| HTML | JSX | 이유 |
|---|---|---|
class |
className |
class는 JS 예약어 |
for |
htmlFor |
for도 JS 예약어 |
onclick |
onClick |
camelCase 규칙 |
| 자동 닫힘 태그 선택 | 반드시 닫아야 함 | XML 기반 문법 |
JSX에서 JavaScript 표현식을 사용하려면 중괄호 {}로 감싸면 된다. 변수, 함수 호출, 삼항 연산자 등 표현식이라면 뭐든 넣을 수 있다. 단, if문이나 for문 같은 구문(statement)은 직접 넣을 수 없다.
Props로 데이터 전달하기
Props는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 방법이다. HTML 속성처럼 생겼지만, 값으로 문자열뿐만 아니라 숫자, 배열, 객체, 심지어 함수까지 넘길 수 있다.
구조 분해 할당(destructuring)을 쓰면 더 깔끔하다. 실무에서는 거의 대부분 이 방식을 사용한다.
Props의 핵심 규칙: 읽기 전용
Props는 부모가 넘겨준 데이터이므로 자식 컴포넌트에서 절대 수정하면 안 된다. 이 규칙은 React의 단방향 데이터 흐름을 유지하는 핵심 원칙이다. 데이터를 변경해야 한다면 State를 사용해야 한다.
컴포넌트 조합 패턴
React의 진짜 강점은 작은 컴포넌트를 조합해서 복잡한 UI를 만드는 데 있다. 아래 예시처럼 카드 하나를 만들고, 그 카드를 리스트로 반복하는 구조가 가장 기본적인 패턴이다.
리스트를 렌더링할 때 key prop은 필수다. React가 어떤 항목이 변경, 추가, 삭제됐는지 판단하는 기준이 된다. 인덱스를 key로 쓰는 건 비추천. 고유한 id가 있다면 그걸 쓰자.
초보자가 자주 하는 실수
컴포넌트 이름을 소문자로 쓰는 경우
<userCard />처럼 소문자로 시작하면 React가 HTML 태그로 인식한다. 항상 대문자로 시작해야 한다.
Props를 직접 수정하는 경우
props.name = "new"처럼 Props를 직접 바꾸면 예측 불가능한 버그가 생긴다. Props는 읽기 전용이라는 규칙을 반드시 지켜야 한다.
return에서 여러 요소를 반환하는 경우
JSX에서 여러 요소를 반환하려면 하나의 부모 요소로 감싸야 한다. 불필요한 <div>를 추가하고 싶지 않다면 <Fragment> 또는 빈 태그 <></>를 사용하면 된다.
마무리
React의 컴포넌트, Props, JSX는 단순하지만 이 세 가지가 React 전체 구조의 토대다. 컴포넌트로 UI를 쪼개고, Props로 데이터를 흘려보내고, JSX로 선언적 UI를 작성한다. 이 흐름을 체득하면 이후에 State, Hooks, 상태 관리 라이브러리를 배울 때도 훨씬 수월해진다.
개념만 읽는 것보다 직접 간단한 컴포넌트를 만들어보는 게 가장 빠르다. 버튼 하나, 카드 하나부터 시작해보자.