React 교재 · 입문 4편

React JSX 문법 — HTML 과 다른 5가지

JSX 는 HTML 처럼 보이지만 JavaScript. 5가지 차이만 머리에 박으면 끝.

코드 에디터 안에서 HTML 태그와 JavaScript 가 중괄호로 자연스럽게 섞이는 일러스트 — JSX 컨셉

3편의 <h1>안녕, React!</h1> 가 JSX. HTML 처럼 보였지만 사실은 JavaScript 표현식. Babel/esbuild 가 컴파일 시 React.createElement('h1', null, '안녕, React!') 같은 함수 호출로 바꾼다. 그래서 JS 변수를 끼울 수 있고, 조건문도 가능하고, 함수도 직접 부른다.

이번 4편은 JSX 와 HTML 의 5가지 차이 + 중괄호 표현식·Fragment·이벤트 핸들러까지. 한 번 정리하면 평생 헷갈릴 일 없다.

1. HTML 과 다른 5가지

처음 JSX 를 보면 익숙하면서 어색하다. 차이가 정확히 5개라서 한 번에 외우는 게 효율적.

차이HTMLJSX
class 속성class="btn"className="btn" (class 는 JS 예약어)
for 속성 (label)for="email"htmlFor="email"
style 속성style="color: red"style={{ color: 'red' }} (객체)
이벤트 이름onclick="..."onClick={handler} (camelCase + 함수)
자기 닫기 태그<br> <img><br /> <img /> (XML 처럼 / 필수)
왜 이렇게 어긋났는가 — JSX 는 JavaScript 안에 들어가는 문법이라 JS 예약어(class·for) 와 충돌. style 은 객체로 받아 동적 계산 가능하게. 이벤트 camelCase 는 DOM 의 onclick 과 구분해 React 의 합성 이벤트(SyntheticEvent) 시스템으로 라우팅하기 위함.

2. 중괄호 표현식 — JSX 의 진짜 힘

JSX 안에서 {...} 중괄호로 JavaScript 표현식 을 끼울 수 있다. 변수·함수 호출·연산 모두 가능.

function Welcome() { const name = '박준성'; const hour = new Date().getHours(); const greeting = hour < 12 ? '좋은 아침' : '안녕'; return ( <div> <h1>{greeting}, {name}님!</h1> <p>현재 {hour}시입니다.</p> <p>2 + 2 = {2 + 2}</p> </div> ); }

중괄호 안에는 표현식 만. if·for 같은 문(statement) 은 못 쓴다. 대신 삼항 연산자, &&, .map() 으로 같은 효과 (8·9편에서 자세히).

속성에도 중괄호

태그 속성에 변수·표현식 넣을 때도 동일:

const url = 'https://junai.ai'; const isActive = true; <a href={url} className={isActive ? 'active' : ''}>링크</a>

3. Fragment — 여러 요소를 한 번에 반환

JSX 의 한 가지 제약 — 컴포넌트는 단일 root 요소만 반환. 여러 형제 요소를 그냥 늘어놓으면 에러.

// ❌ 에러 function List() { return ( <li>첫번째</li> <li>두번째</li> ); }

해결책은 두 가지. <div> 같은 wrapper 로 감싸거나 (불필요한 DOM 추가), Fragment 사용 (DOM 추가 없음, 권장).

// ✅ Fragment 단축 문법 function List() { return ( <> <li>첫번째</li> <li>두번째</li> </> ); } // 또는 명시적으로 <React.Fragment>...</React.Fragment>

Fragment 가 진가를 발휘하는 케이스 — 테이블 row 컴포넌트, <dt> + <dd> 쌍, 부모 레이아웃을 깨고 싶지 않을 때. 9편 리스트 렌더링에서 key 가 필요한 경우는 명시적 Fragment 만 가능 (단축 문법은 key 안 받음).

4. 이벤트 핸들러 — 함수 자체를 전달

JSX 이벤트의 핵심 — 함수를 호출하지 말고 함수 자체를 전달.

function Button() { const handleClick = () => { alert('클릭됨!'); }; return ( <> <button onClick={handleClick}>✅ 정답</button> <button onClick={handleClick()}>❌ 즉시 호출됨 (마운트 시 1번)</button> <button onClick={() => alert('인라인')}>✅ 화살표 인라인</button> </> ); }

두 번째 패턴이 가장 흔한 초보 실수. 괄호를 붙이면 렌더링 시점에 함수가 즉시 실행되고 그 반환값(undefined)이 핸들러로 등록된다. 괄호 없는 함수 참조를 전달해야 클릭 시점에 호출.

인자 전달 패턴 — 핸들러에 인자를 넘기고 싶을 때는 인라인 화살표로 감싼다. onClick={() => deleteItem(id)} 패턴. 직접 onClick={deleteItem(id)} 하면 위와 같은 즉시 호출 버그.

4편 끝 — JSX 의 모든 기본기 정리 완료. 5편에서는 컴포넌트 사이 데이터 전달 (props) 으로 들어간다. 함수 인자와 똑같은 개념이 JSX 속성으로 표현된다.

다음 글

React 교재 5편 — Props 로 부모→자식 데이터 전달. 구조분해 패턴, children prop, TypeScript 타입까지.

© 2026 주나이테크(주) @JUNAITECH