Search

JSX 문법

JSX는 자바스크립트에서 XML을 사용하기 위해 확장시킨 버전입니다. 리액트에서 JSX를 사용하는 것이 필수는 아니지만, JSX를 사용하는 것이 리액트 개발을 훨씬 쉽게 만들어줍니다. JSX가 HTML을 XML 포멧을 통해 자바스크립트와 함께 사용할 수 있게 만들어주기 때문이죠.
const jsxHeadline = <h1>Hello, JSX!</h1>;
JavaScript
복사
JSX를 통해 HTML 태그를 자바스크립트와 함께 사용할 수 있습니다.
XML 또한 HTML처럼 마크업 언어 태생이기 때문에 HTML 파일에서 작성하는 것과 매우 유사한 느낌으로 JSX에서 HTML을 작성할 수 있습니다. 꺽쇄기호<>를 사용한 태그 작성법과 부모 자식과 같은 관계도 동일하게 적용됩니다.
하지만 XML은 데이터의 저장과 교환에 용이하도록 만들어진 범용적으로 사용되는 언어로 HTML과 비교해 두가지 작성 규칙 차이가 존재합니다.
1.
HTML은 대소문자를 구분하지 않지만, XML에서는 대소문자를 구분한다.
2.
HTML은 기본 닫기 태그가 있지만, XML에서는 태그는 무조건 닫아줘야 한다.
JSX에서 사용하는 태그는 XML 규칙을 따르기 때문에 위 차이점은 JSX에도 적용됩니다. 1번의 경우 자바스크립트 또한 대소문자를 구분하므로 JSX에서 자바스크립트와 HTML을 함께 사용할때 보다 용이하도록 만들어 줍니다. 하지만 2번의 경우 HTML에서 <input>과 같은 기본 닫기가 있는 태그를 그대로 사용하면 에러가 발생하게 되므로 주의해야 합니다.
JSX가 컴파일 과정을 통해 최종적으로 자바스크립트 코드가 된다는 것을 생각해야 합니다. 따라서 JSX에서 HTML을 함께 사용하더라도 자바스크립트 기준에 맞춰서 작성해야 합니다. 자바스크립트에서 DOM API 사용할 때처럼 onclick처럼 소문자로만 되어있는 HTML의 속성 코드를 onClick과 같이 카멜케이스(camelCase) 형태로 바꿔서 사용하는 식이죠.
그럼 본격적으로 몇가지 주의점과 함께 JSX 문법을 하나씩 알아봅시다.

두줄 이상의 JSX 코드는 소괄호() 로 감싸기

자바스크립트에서 소괄호()는 괄호 안의 요소들을 묶어주는 기능을 합니다.
JSX 코드가 두줄 이상(멀티 라인)이 될 경우 소괄호로 묶어줘야 컴파일러가 안정적으로 JSX 코드를 인식합니다.
const jsxMultiline = ( <ul> <li>철수</li> <li>영희</li> </ul> );
JavaScript
복사
JSX 코드가 멀티라인이 되더라도 JSX 코드부터 시작하게 된다면 소괄호로 묶어주지 않아도 에러가 발생하지는 않습니다.
const jsxMultiline = <ul> <li>철수</li> <li>영희</li> </ul>;
JavaScript
복사
태그로 시작하는 JSX 코드는 소괄호로 감싸주지 않아도 되지만 두줄 이상일때 가시성이 좋지 않습니다.
하지만 가시성 문제와 VS Code와 같은 에디터에서 에러로 인식하는 경우가 있기 때문에 두줄 이상의 멀티라인 JSX 코드는 소괄호로 감싸서 작성하는 것이 일반적입니다.
또한 보다 복잡한 자바스크립트의 표현식과 같이 사용할때 JSX 코드를 소괄호로 감싸 경계를 만들어주지 않으면 에러가 발생할 위험이 커집니다. 화살표 함수의 경우 함수의 스코프를 뜻하는 중괄호{}와 JSX 코드 안에서 자바스크립트 사용을 뜻하는 중괄호{}가 서로 문법 충돌을 일으켜 컴파일러가 에러를 발생시킬 수 있습니다.
따라서 필수는 아니지만 개발할때 두줄 이상의 JSX 코드는 원칙적으로 소괄호로 감싸주는 것이 안전합니다.

하나의 최상위 태그로 감싸기

JSX 코드에서는 하나의 최상위 태그만 존재할 수 있습니다. 아래 경우처럼 두개 이상의 형제 태그가 최상위에 나란히 존재하면 에러가 발생합니다.
const todo = ( <h1>할일</h1> <p>리액트 공부하기</p> );
JavaScript
복사
 JSX 코드 최상위에 두개 이상의 태그가 존재하면 컴파일 에러가 발생합니다.
두개 이상의 태그가 최상위에 존재하는 경우, 하나의 태그를 나머지 태그들의 부모로 감싸서 묶어주면 해결됩니다. 보통 최상위 부모 태그로 <div> 태그를 많이 사용합니다.
const todo = ( <div> <h1>할일</h1> <p>리액트 공부하기</p> </div> );
JavaScript
복사
 최상위를 하나의 태그로 감싸주면 에러가 발생하지 않습니다.
불필요한 div를 추가하는 것이 문제가 된다면 fragment로 감싸주는 것도 한가지 방법입니다. fragment 사용은 <>, </> 태그로 감싸주면 됩니다.
const todo = ( <> <h1>할일</h1> <p>리액트 공부하기</p> </> );
JavaScript
복사
fragment로 감싸주면 불필요한 노드를 DOM에 추가하지 않고 JSX에서도 에러가 발생하지 않습니다.

JSX에서 태그는 항상 닫기 필요

앞서 JSX에서 HTML은 XML 위에서 작성된다고 설명 드렸었죠? 그렇기 때문에 HTML에서는 생략해도 됬던 태그 닫기가 XML을 사용하는 JSX에서는 항상 필수입니다.
const inputElement = <input name="not-closed">;
JavaScript
복사
 JSX에서는 태그는 항상 닫기 처리를 해야하기 때문에 위 코드는 에러가 발생합니다.
<input> 태그 같은 경우 HTML에서는 닫기를 생략해도 되는 태그였지만 JSX에서는 아닙니다. 셀프 닫기나 닫기 태그를 선언해야 에러가 발생하지 않습니다.
const inputElement1 = <input name="self-closed" />; const inputElement2 = <input name="closed"></input>;
JavaScript
복사
 JSX에서 태그는 항상 닫기를 선언해야 에러가 발생하지 않습니다.

JSX 코드 안에서 자바스크립트의 사용

JSX 코드에서 중괄호{}를 사용하면 자바스크립트 표현을 JSX 코드 안에서 사용할 수 있습니다.
const title = 'JSX 문법'; const element = ( <h1>이번 스터디는 {title}에 관한 내용입니다.</h1> );
JavaScript
복사
JSX 안에서 자바스크립트로 수식을 작성하면 계산된 결과를 보여주게 됩니다.
const element = ( <h1>1 더하기 2{1 + 2}</h1> ); // 1 더하기 2는 3
JavaScript
복사
함수를 호출해서 사용할 수도 있습니다.
function calculate(a, b) { return a + b; } const element = ( <h1>1 더하기 2{calculate(1, 2)}</h1> ); // 1 더하기 2는 3
JavaScript
복사
if, else, else if 와 같은 자바스크립트 조건식은 JSX 코드 내에서는 사용할 수 없습니다. if 와 같은 조건식은 JSX 외부에서 선언해서 사용해야 합니다.
let result; const condition = Math.random(); // 0에서 1보다 작은 랜덤 값 if (condition >= 0.5) { result = '홀'; } else { result = '짝'; } const element = ( <p>결과는 {result}입니다.</p> );
JavaScript
복사
JSX 내부에서 if, else 와 같은 조건식은 사용할 수 없지만, 삼항연산자(?:)는 사용 가능하므로 이를 활용할 수 있습니다.
const condition = Math.random(); // 0에서 1보다 작은 랜덤 값 const element = ( <p>결과는 {condition >= 0.5 ? '홀' : '짝'}입니다.</p> );
JavaScript
복사
AND 연산자(&&)를 if 대신 사용할 수도 있습니다.
const isNew = true; const element = ( <p>저는 {isNew && '신규 '}참가자 입니다.</p> );
JavaScript
복사
isNew가 true 일때만 ‘신규 ‘ 텍스트가 보여집니다.
JSX 내부에서 주석의 사용은 중괄호와 함께 블록형 주석 /* */ 만 가능합니다. 인라인 주석인 // 을 JSX식 내부에서 사용할 경우 컴파일 에러가 발생합니다.
const element = ( {/* JSX식 내에서 주석은 블록 주석만 사용 가능합니다. */} <div></div> );
JavaScript
복사

태그 속성은 카멜 케이스 사용

JSX의 HTML을 컴파일 과정을 통해 자바스크립트로 변환됩니다. JSX 자체는 HTML보다는 자바스크립트에 더 가깝다고 볼 수 있죠. 그리고 XML 기반이기 때문에 대소문자를 구별하므로, JSX에서 속성 사용할때는 자바스크립트에서 직접 DOM 속성을 핸들링 할때 사용했던 것처럼 카멜케이스(camelCase) 형태로 사용해야 합니다.
function clickHandler() { alert('클릭!'); } const element = ( <button onClick={clickHandler}>버튼</button> );
JavaScript
복사
JSX에서 태그의 속성을 선언할때 onclick이 아닌 onClick처럼 카멜케이스 형태로 선언해야 합니다.

style 속성은 카멜케이스를 사용한 객체로 추가

속성과 마찬가지로 자바스크립트에서 DOM 노드에 스타일 요소를 추가할때 카멜케이스 형태로 사용합니다. JSX에서는 style 속성에 카멜케이스로 정의한 스타일 객체를 포함시켜 적용합니다.
const h1Style = { fontSize: '32px', color: 'white', }; const element = ( <div style="{{ backgroundColor: 'black', width: '100%', height: '100vh', }}" > <h1 style="{h1Style}"> 스타일 적용된 JSX </h1> </div> );
JavaScript
복사
HTML이나 CSS에서 사용하던 케밥케이스(kebab-case) 형태의 스타일 요소를 카멜케이스(camelCase) 형태로 바꾸어서 사용해야 합니다. 예) font-size → fontSize

class 속성은 className으로 바꿔서 사용

JSX에서 자바스크립트도 함께 사용하기 때문에 HTML 태그의 class 속성과 자바스크립트의 class 예약어가 충돌하는 문제가 발생합니다. 그렇기 때문에 JSX에서는 HTML 태그의 class 속성을 className으로 고쳐서 사용 합니다.
const element = ( <div className="css-class"></div> );
JavaScript
복사

for 속성은 htmlFor로 바꿔서 사용

class의 경우와 마찬가지 입니다. for 속성은 자바스크립트의 for 예약어와 겹치기 때문에 JSX에서 사용할 수 없습니다. JSX에서는 HTML 태그의 for 속성을 htmlFor로 고쳐서 사용합니다.
const element = ( <> <label htmlFor="email-field">이메일 주소</label> <input id="email-field" /> </> );
JavaScript
복사

JSX 코드는 리액트 element로 컴파일

JSX 코드로 작성한 UI 요소(element)는 컴파일 과정을 거쳐 React element가 됩니다. 일반 자바스크립트에서 리액트 함수를 사용해 React Element를 생성한 것과 랜더링 했을때 같은 결과를 보여줍니다.
아래 리액트의 createElement 함수를 통해 생성한 element와,
const element = React.createElement( 'h1', {}, 'React Element' ); // 리액트 랜더 코드 (18 버전 이상) const rootNode = document.getElementById('root'); ReactDOM.createRoot(rootNode).render(element);
JavaScript
복사
일반 자바스크립트로 리액트 element 생성 (.js)
아래 JSX 코드로 작성한 element는 리액트로 랜더링 했을때 같은 결과를 보여줍니다.
const element = <h1>React Element</h1>; // 리액트 랜더 코드 (18 버전 이상) const rootNode = document.getElementById('root'); ReactDOM.createRoot(rootNode).render(element);
JavaScript
복사
JSX로 리액트 element 생성 (.jsx)

 React란?

 컴포넌트(component)와 props

React 시작하기 목록