FRONTEND

React Components, Props, and JSX: A Beginner's Guide

junetapa 2025. 8. 18 2026. 6. 5 업데이트 10 min read

React를 시작할 때 가장 먼저 만나는 세 가지 개념이 있다. 컴포넌트, Props, 그리고 JSX. 이 셋만 제대로 이해하면 React의 절반은 끝난 셈이다. 복잡한 이론 없이, 실제 코드와 함께 핵심만 짚어본다.

2026년 6월 업데이트

이 글은 React 19 정식 버전(2024년 12월 안정화) 기준으로 내용을 최신화했다. 2026년 현재 함수형 컴포넌트는 사실상 유일한 표준이고, 클래스 컴포넌트와 forwardRef는 레거시로 밀려났다. 입문 단계에서 알아야 할 핵심 개념은 그대로지만, ref를 일반 prop처럼 전달하는 방식, Actions·useActionState·use(), 서버 컴포넌트(RSC) 같은 React 19의 변화를 함께 짚어 두었다.

컴포넌트란 무엇인가

React에서 컴포넌트는 UI를 구성하는 독립적인 조각이다. 레고 블록이라고 생각하면 쉽다. 버튼 하나, 헤더 하나, 카드 하나가 각각 컴포넌트가 될 수 있고, 이 블록들을 조합해서 전체 페이지를 만든다.

2026년 기준으로 함수형 컴포넌트가 사실상 유일한 표준이다. React 19 정식 버전이 자리 잡으면서 클래스 컴포넌트는 오래된 레거시 프로젝트에서만 볼 수 있고, 새로 시작하는 프로젝트라면 함수형으로 작성하는 것이 당연하게 여겨진다. 함수 하나가 곧 컴포넌트이고, 그 함수가 반환하는 것이 화면에 보이는 UI다.

JSX - 함수형 컴포넌트 기본 형태
function Welcome() {
    return <h1>안녕하세요</h1>;
}

이게 전부다. 함수 이름이 컴포넌트 이름이 되고, return 뒤에 오는 JSX가 화면에 렌더링된다. 함수 이름은 반드시 대문자로 시작해야 한다. React가 HTML 태그와 커스텀 컴포넌트를 구분하는 기준이기 때문이다.

핵심 정리
  • 컴포넌트 = UI를 반환하는 JavaScript 함수
  • 이름은 반드시 대문자로 시작 (PascalCase)
  • 하나의 컴포넌트는 하나의 역할만 담당하는 것이 이상적
  • 재사용 가능하게 설계하는 것이 핵심

JSX, HTML처럼 생긴 JavaScript

JSX는 JavaScript 안에서 HTML 같은 문법을 쓸 수 있게 해주는 확장 문법이다. 브라우저가 직접 이해하는 건 아니고, Babel이나 Vite 같은 빌드 도구가 일반 JavaScript로 변환해준다. 참고로 React 17부터 도입된 새 JSX 변환(automatic runtime) 덕분에, 요즘은 JSX만 쓰는 파일이라면 굳이 import React from 'react'를 맨 위에 적지 않아도 된다.

JSX - JSX vs 변환 결과
// JSX 방식
const element = <h1 className="title">Hello</h1>;

// 새 JSX 변환이 만들어내는 코드(개념적으로)
import { jsx as _jsx } from 'react/jsx-runtime';
const element = _jsx('h1', { className: 'title', children: 'Hello' });

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 속성처럼 생겼지만, 값으로 문자열뿐만 아니라 숫자, 배열, 객체, 심지어 함수까지 넘길 수 있다.

JSX - Props 전달과 사용
// 부모 컴포넌트
function App() {
    return <UserCard name="junetapa" role="developer" />;
}

// 자식 컴포넌트
function UserCard(props) {
    return (
        <div>
            <h2>{props.name}</h2>
            <p>{props.role}</p>
        </div>
    );
}

구조 분해 할당(destructuring)을 쓰면 더 깔끔하다. 실무에서는 거의 대부분 이 방식을 사용한다.

JSX - 구조 분해 할당으로 Props 받기
function UserCard({ name, role }) {
    return (
        <div>
            <h2>{name}</h2>
            <p>{role}</p>
        </div>
    );
}

Props의 핵심 규칙: 읽기 전용

Props는 부모가 넘겨준 데이터이므로 자식 컴포넌트에서 절대 수정하면 안 된다. 이 규칙은 React의 단방향 데이터 흐름을 유지하는 핵심 원칙이다. 데이터를 변경해야 한다면 State를 사용해야 한다.

ref도 이제 그냥 prop이다 (React 19)

예전에는 자식 컴포넌트에 DOM 참조(ref)를 넘기려면 forwardRef로 컴포넌트를 감싸야 했다. React 19부터는 ref를 다른 props와 똑같이 받아 쓸 수 있게 바뀌었다. 입문 단계에서 당장 쓸 일은 적지만, 오래된 예제에서 forwardRef가 보인다면 "지금은 굳이 안 써도 되는 옛 방식"이라고 이해하면 된다.

JSX - ref를 prop으로 받기 (React 19)
function MyInput({ placeholder, ref }) {
    return <input placeholder={placeholder} ref={ref} />;
}
부모에서 자식으로 프롭스가 한 방향으로 흐르는 구조를 나타낸 도해
데이터는 위에서 아래로만 흐른다 — 그것이 React 의 기본 규칙이다.

컴포넌트 조합 패턴

React의 진짜 강점은 작은 컴포넌트를 조합해서 복잡한 UI를 만드는 데 있다. 아래 예시처럼 카드 하나를 만들고, 그 카드를 리스트로 반복하는 구조가 가장 기본적인 패턴이다.

JSX - 컴포넌트 조합
function PostCard({ title, description }) {
    return (
        <div className="card">
            <h3>{title}</h3>
            <p>{description}</p>
        </div>
    );
}

function PostList() {
    const posts = [
        { id: 1, title: 'React 입문', description: '컴포넌트 기초' },
        { id: 2, title: 'Props 이해', description: '데이터 전달법' },
    ];

    return (
        <div>
            {posts.map(post =>
                <PostCard key={post.id} title={post.title} description={post.description} />
            )}
        </div>
    );
}
주의

리스트를 렌더링할 때 key prop은 필수다. React가 어떤 항목이 변경, 추가, 삭제됐는지 판단하는 기준이 된다. 인덱스를 key로 쓰는 건 비추천. 고유한 id가 있다면 그걸 쓰자.

초보자가 자주 하는 실수

컴포넌트 이름을 소문자로 쓰는 경우

<userCard />처럼 소문자로 시작하면 React가 HTML 태그로 인식한다. 항상 대문자로 시작해야 한다.

Props를 직접 수정하는 경우

props.name = "new"처럼 Props를 직접 바꾸면 예측 불가능한 버그가 생긴다. Props는 읽기 전용이라는 규칙을 반드시 지켜야 한다.

return에서 여러 요소를 반환하는 경우

JSX에서 여러 요소를 반환하려면 하나의 부모 요소로 감싸야 한다. 불필요한 <div>를 추가하고 싶지 않다면 <Fragment> 또는 빈 태그 <></>를 사용하면 된다.

JSX - Fragment 사용
function Profile() {
    return (
        <>
            <h1>이름</h1>
            <p>소개</p>
        </>
    );
}
컴포넌트 이름 대문자와 키 지정 등 리액트 초보자가 자주 하는 실수를 정리한 도해
처음에 가장 자주 걸리는 네 가지다.

마무리

React의 컴포넌트, Props, JSX는 단순하지만 이 세 가지가 React 전체 구조의 토대다. 컴포넌트로 UI를 쪼개고, Props로 데이터를 흘려보내고, JSX로 선언적 UI를 작성한다. 이 흐름을 체득하면 이후에 State, Hooks, 상태 관리 라이브러리를 배울 때도 훨씬 수월해진다.

여기까지 익혔다면 다음 단계로 React 19에서 강화된 기능들을 천천히 살펴봐도 좋다. 폼 처리와 비동기 동작을 묶어주는 ActionsuseActionState, Promise를 렌더링 흐름에 자연스럽게 끼워 넣는 use() 훅, 그리고 서버에서 실행되어 클라이언트 번들을 가볍게 만드는 서버 컴포넌트(RSC)가 대표적이다. 다만 이들은 기초가 잡힌 뒤에 접근하는 것이 좋고, 상태 관리는 2026년 현재 Zustand, 서버 데이터는 TanStack Query가 사실상 표준처럼 쓰인다는 점만 기억해 두자.

개념만 읽는 것보다 직접 간단한 컴포넌트를 만들어보는 게 가장 빠르다. 버튼 하나, 카드 하나부터 시작해보자.

참고

React 19 공식 안내는 react.dev의 React v19 릴리스 노트에서 확인할 수 있다. 입문 단계에서는 이 글의 컴포넌트·Props·JSX 흐름만 확실히 잡아도 충분하다.

React Components Props JSX Frontend React 입문
junetapa
junetapa
프론트엔드와 개발자가 아니라 쓰는 사람. IT 현장 27년의 기준으로 AI 도구를 고르고 기록한다.
Twitter Facebook URL 복사