JSX란?
JavaScript를 확장한 문법이며 XML과 매우 유사하게 생겼다. 외관상 HTML같은 마크업 언어를 리터럴로 입력하는 것으로 보이는데, 빌드 시 Babel에 의해 자바스크립트로 변환된다. (공식적인 자바스크립트 문법은 아니다)
function App(){
return (
<div>
Hello <b>react</b>
</div>
);
}
위 코드는 아래의 코드로 랜더링된다
function App(){
return React.createElement("div", null, "Hello", React.createElement("b", null "react"));
}
컴포넌트를 랜더링 할 때마다 React.createElement를 하는 것은 매우 번거로울 것이다. JSX를 사용하면 보다 편하게 UI를 랜더링 할 수 있다.
React는 JSX 사용이 필수가 아니지만, JavaScript 코드 안에서 UI 관련 작업을 할 때 시각적으로 도움이 된다. 또한 React 개발에 도움이 되는 에러 및 경고 메시지를 표시할 수 있게 해준다.
JSX의 장점
- 보기 쉽고 익숙하다
일반 자바스크립트만 사용한 코드와 JSX로 작성한 코드를 비교해보면, 몇 초만 보아도 JSX를 사용하는 편이 더욱 가독성이 높고 작성하기 쉽다는 것을 느낄 수 있다. HTML코드를 작성하는 것과 비슷하기 때문이다. - 높은 활용도
JSX에서는 HTML태그를 사용할 수 있을 뿐만 아니라, 앞으로 만들 컴포넌트도 JSX안에서 작성할 수 있다.
JSX 문법
1. 감싸인 요소
요소 여러 개가 하나의 부모 요소 의하여 감싸져있어야 한다.
import React from 'react';
// 잘못된 코드
function App(){
return(
<h1>Hello</h1>
<h2>Is it working well?</h2>
)
}
// 올바른 코드
function App(){
return(
<div>
<h1>Hello</h1>
<h2>Is it working well?</h2>
</div>
)
}
export default App;
하나의 부모 요소로 감싸져 있어야 하는 이유는 Virtual DOM에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문이다.
<div>대신 <>(fragment tag)를 사용하여 자식 요소들을 감싸주어도 된다.
2. 자바스크립트 표현
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Harper',
lastName: 'Perez'
};
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
JSX 안에서 자바스크립트 표현식을 쓸 수 있다. 자바스크립트 표현식을 작성하려면 JSX 내부에서 코드를 { }로 감싸면 된다.
3. If 문 사용 불가
import React from ‘react‘;
function App() {
const name = ‘리액트‘;
return (
<div>
{name === ‘리액트‘ ? (
<h1>리액트입니다.</h1>
) : (
<h2>리액트가 아닙니다.</h2>
)}
</div>
);
}
export default App;
JSX 내부의 자바스크립트 표현식에서 if 문을 사용할 수 없다. 조건에 따라 다른 내용을 렌더링해야 할 때는 JSX 밖에서 if 문을 사용하여 사전에 값을 설정하거나, { } 안에 조건부 연산자(삼항 연산자)를 사용한다.
import React from ‘react‘;
function App() {
const name = ‘react‘;
return <div>{name === ‘리액트‘ && <h1>리액트입니다.</h1>}</div>;
}
export default App;
혹은 AND 연산자(&&)를 사용하여 조건을 모두 만족할 때만 값을 보여주도록 해 줄 수 있다. && 연산자로 조건부 렌더링을 할 수 있는 이유는 리액트에서 false를 렌더링할 때는 null과 마찬가지로 아무것도 나타나지 않기 때문이다.
4. undefined를 렌더링하지 않기
import React from 'react';
import './App.css';
// undefined를 렌더링 하지 않기
function App(){
const name = 'undefined';
return name;
}
export default App;
위 코드를 실행해 보면 아래와 같은 오류가 발생한다.
App(...): Nothing was returned from render. This usually means a return statement is missing.
Or, to render nothing, return null
반면, JSX 내부에서 undefined를 렌더링 하는 것은 괜찮다
import React from 'react';
import './App.css';
function App(){
const name = 'undefined';
return <div>{name}</div>
}
export default App;
5. 인라인 스타일링
리액트에서 DOM 요소에 스타일을 적용할 때는 문자열 형태로 넣는 것이 아니라 객체 형태로 넣어 주어야한다. 스타일 이름 중에서 background-color처럼 - 문자가 포함되는 이름은 - 문자를 없애고 카멜 표기법(camelCase)으로 작성해야 한다. 따라서 background-color는 backgroundColor로 작성한다.
6. 꼭 닫아야 하는 태그
input HTML 요소는 <input></input>이라 입력하지 않고 <input>이라고만 입력해도 작동한다. 하지만 JSX에서는 태그를 닫지 않으면 오류가 발생한다.
태그 사이에 별도의 내용이 들어가지 않는 경우에는 self-closing 태그(태그를 선언하면서 동시에 닫을 수 있는 태그)를 사용할 수 있다.
참조
'React' 카테고리의 다른 글
[React] 함수형 컴포넌트는 렌더링된 값들을 고정시킨다 (1) | 2022.09.14 |
---|---|
[React] Virtual DOM and Rendering (2) | 2022.05.29 |
Ref (0) | 2022.05.04 |
[React] Props, State (0) | 2021.11.12 |