React : JSX(JavaScript XML)

JSX(JavaScript XML)

이전 글에서 App.js 자바스크립트 파일 내에 코드를 변경하여 브라우저 화면(HTML)이 수정된 것을 확인할 수 있었다.

원래 HTML의 변경은 .html 파일에 적어야 하지만 그런데 .js파일에 코드를 수정해도 HTML이 변경되는 이유가 뭘까?

바로 App.js, return 내부의 코드들은 HTML코드가 아니기 때문이다. 바로 JSX 이다.

JSX는 자바스크립트를 확장한 언어로 자바스크립트 파일 내에서 HTML코드를 사용할 수 있게 해준다.

즉, 리액트는 JSX를 사용하여 HTML과 JavaScript를 결합한다.

JSX는 HTML 코드와 비슷하기 때문에 일반 자바스크립트만 사용한 코드보다 더 익숙하고 간결하며 가독성이 좋다.

추가로 JSX에서는 HTML 태그들과 똑같이 사용할 수 있으며, 개발자가 생성한 컴포넌트(Component)들도 JSX 안에서 사용할 수 있다.

하지만 브라우저는 이러한 JSX 언어를 이해하지 못하여 브라우저가 인식할 수 있도록 Babel이라는 도구로 JSX문법을 자바스크립트 문법으로 바꿔주어야 한다.

JSX 문법 규칙

1. 반드시 부모 요소 하나가 감싸는 형태여야 한다.

virtual DOM에서 컴포넌트 변화를 감지할 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM Tree 구조로 이루어져야 한다는 규칙이 있기 때문이다.
// 정상 코드
function App() {
  return (
    <div>
      <div>반드시 부모 요소 하나가 감싸는 형태여야 한다.</div>
    </div>
  );
}

// 에러 코드
function App() {
  return (
    <div>반드시 부모 요소 하나가</div>
    <div>감싸는 형태여야 한다.</div>
  );
}

🚨 에러 : Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (6:4)

상기 잘못된 코드처럼 하나의 부모 요소로 감싼 형태가 아니라면 해당 에러가 발생한다.

2. 무조건 모든 태그를 닫아준다.

function App() {
  return (
    <div>
      <p>무조건 모든 태그를 닫아준다.
    </div>
  );
}

🚨 에러 : Unterminated JSX contents.

태그가 닫히지 않으면 해당 에러가 일어나게 된다.

3. 자바스크립트 표현식 사용

JSX에서도 자바스크립트와 마찬가지로 {}를 사용하여 변수에 저장된 데이터를 가져올 수 있다.

마찬가지로 DB나 서버의 데이터를 가져올 때도 {}를 사용해주고 {}는 JSX 내부 어디에서나 사용 가능하다.

{} 내부에서는 변수, 수식, 속성 등 유효한 자바스크립트 표현식을 모두 작성할 수 있다.
function App() {
  let name = 'yyummmmmmmm';
  return (
    <div>
      <h3 id={name}>yyummmmmmmm</h3>
      <h4>{name}</h4>
      <p>{10 * 10}</p>
    </div>
  );
}

4. if문(for문) 대신 삼항 연산자(조건부 연산자) 사용

if문과 for문은 자바스크립트 표현식이 아니기 때문에 JSX 내부에서 사용할 수 없다.

대신 JSX 밖에서 사용하거나, JSX 내부에서는 삼항 연산자(조건부 연산자)를 사용할 수 있다.
// 방법 1 : JSX 바깥에서 사용
function App() {
	let text = '';
	const login = 'Y';
	if(login === 'Y') {
		text = <div>회원 입니다.</div>;
	} else {
		text = <div>비회원 입니다.</div>;
	}
	return (
		<div>
			{desc}
		<div>
	);
}

// 방법 2 : JSX 내부에서 삼항 연산자 사용
function App() {
	const login = 'Y';
	return (
		<div>
			{login === 'Y' ? (<div>회원 입니다.</div>) : (<div>비회원 입니다.</div>)}
		<div>
	);
}

// 방법 3 : AND 연산자(&&) 사용, 조건이 만족하지 않을 경우 아무것도 노출되지 않는다.
function App() {
	const login = 'Y';
	return (
		<div>
			{login === 'Y' && <div>회원 입니다.</div>}
		<div>
	);
}

// 방법 4 : 즉시 실행 함수 사용
function App() {
	const login = 'Y';
	return (
		<div>
			{
			  (() => {
				if(login === "Y"){
				  return (<div>회원 입니다.</div>);
				}else{
				  return (<div>비회원 입니다.</div>);
				}
			  })()
			}
		</div>
	);
}

5. 모든 프로퍼티 이름은 카멜케이스로 작성한다.

JSX에서의 모든 프로퍼티 이름은 카멜케이스 방식을 따른다.

JSX는 HTML보단 자바스크립트에 가깝기 때문에 React DOM은 HTML 어트리뷰트 이름 대신 카멜케이스 프로퍼티 명명 규칙을 사용한다. 자바스크립트에서도 메소드 작성 네이밍이 카멜케이스가 일반적인 규칙인 것과 같다.

프로퍼티를 카멜케이스로 작성하는 네이밍 규칙을 준수하지 않으면, 에러 메시지가 표시될 수 있다.
✨ 참고, 컴포넌트명은 반드시 대문자 시작
"리액트 사용 중 컴포넌트명이 소문자 시작하여 에러가 꽤나 많이 발생했었다. 주의하자!"

6. className 사용

기존에 CSS 적용을 위해 태그 내에 class에 CSS 클래스명을 입력하여 CSS 적용을 하였다.

JSX 문법에서는 차이점이 존재하는데 JSX 안에서는 class대신에 className을 입력하여 CSS를 적용해줘야한다는 점이다.

자바스크립트에서의 class는 클래스를 선언할 때 사용하는 예약어로 사용되기 때문에 사용 용도가 다르나 이름이 겹쳐 별도로 className을 사용해야한다.
// 정상 코드
function App() {
  let name = 'yyummmmmmmm';
  return (
    <div className="pink">
      <div>
        <h3 id={name}>yyummmmmmmm</h3><br/>
        <h4>{name}</h4><br/>
        <p>{10 * 10}</p>
      </div>    
    </div>
  );
}

// 에러 코드
function App() {
  let name = 'yyummmmmmmm';
  return (
    <div class="pink">
      <div>
        <h3 id={name}>yyummmmmmmm</h3><br/>
        <h4>{name}</h4><br/>
        <p>{10 * 10}</p>
      </div>    
    </div>
  );
}
.pink {
  display: flex;
  background-color: lightpink;
  width: 100%;
  color: white;
  padding-left: 50px;
}

7. 인라인 style

css 파일말고도 인라인 style을 넣을 때는 style={{스타일명 : '값', 스타일명 : '값', ...}} 이렇게 적용한다.

주의할 점으로 background-color, font-size와 같이 - 기호가 있는 경우에는 이 처럼 backgroundColor, fontSize 카멜케이스로 변경해주어야한다. 왜냐하면 자바스크립트에서의 - 기호는 뺄셈 연산 기호이기 때문이다.
// 정상 코드
function App() {
  let name = 'yyummmmmmmm';
  return (
    <div className="pink">
      <div>
        <h3 id={name}>yyummmmmmmm</h3><br/>
        <h4 style={{backgroundColor:'black', fontSize:'30pt'}}>{name}</h4><br/>
        <p>{10 * 10}</p>
      </div>    
    </div>
  );
}

// 에러 코드
function App() {
  let name = 'yyummmmmmmm';
  return (
    <div className="pink">
      <div>
        <h3 id={name}>yyummmmmmmm</h3><br/>
        <h4 style={{background-color:'black', font-size:'30pt'}}>{name}</h4><br/>
        <p>{10 * 10}</p>
      </div>    
    </div>
  );
}

// 에러는 안나지만 카멜케이스로 작성되지 않아 스타일 적용이 안됨
function App() {
  let name = 'yyummmmmmmm';
  return (
    <div className="pink">
      <div>
        <h3 id={name}>yyummmmmmmm</h3><br/>
        <h4 style={{backgroundcolor:'black', fontsize:'30pt'}}>{name}</h4><br/>
        <p>{10 * 10}</p>
      </div>    
    </div>
  );
}

정상 코드

카멜케이스로 작성되지 않을 경우 (에러는 안나지만 스타일 적용이 안됨)

🚨 에러 : Unexpected token, expected "," (9:30)

스타일 적용 시 기존 코드와 동일하게 - 기호가 들어간다면 해당 에러 발생

8. JSX 주석

JSX 내부에서 주석은 {/* 내용 작성 */} 이렇게 사용한다.
function App() {
  let name = 'yyummmmmmmm';
  return (
    <div className="pink">
      <div>
        <h3 id={name}>yyummmmmmmm</h3><br/>
        <h4 style={{backgroundcolor:'black', fontsize:'30pt'}}>{name}</h4><br/>
        <p>{10 * 10}</p> {/* JSX 주석 */}
      </div>    
    </div>
  );
}

Reference

🙏 React : JSX 소개
🙏 dayannne : React | 알아보자, JSX 작성 규칙 7가지!
🙏 Haizel  : JSX는 무엇인가 (정의, 장점, 규칙, 컴파일)
🙏 갓대희's 작은공간 : [React] 2. JSX란? (정의, 장점, 문법)

'Front > React' 카테고리의 다른 글

React : 컴포넌트(Component)  (1) 2024.11.24
React : props and state  (0) 2024.11.24
React : 개요 및 개발환경 세팅  (2) 2024.11.17