JSX란?
JSX(JavaScript XML)는 Javascript에 XML을 추가한 확장한 문법입니다.
function App() {
return (
<div>
Hello <b>react</b>
</div>
);
}
이런 형식으로 작성한 코드는 브라우저에서 실행되기 전에 코드가 번들링되는 과정에서 바벨을 사용하여
일반 자바스크립트 형태의 코드로 다음과 같이 변환됩니다.
function App() {
return React.createElement("div", null, "Hello", React.createElement("b", null, "react"));
}
JSX를 사용하면 매우 편하게 UI를 렌더링할 수 있습니다.
두 가지 코드를 비교해 보았을때 JSX를 사용하는 편이 가독성이 높고 HTML 코드를 작성하는 것과 비슷해 쉽다고 느껴집니다. 이것이 JSX를 사용하는 주된 이유입니다.
또한 우리가 알고있는 div나 span 같은 HTML 태그를 사용할 수 있을 뿐만 아니라, 컴포넌트도 JSX 안에서 작성할 수 있습니다.
JSX 문법
JSX는 정말 편리한 문법이지만, 올바르게 사용하려면 몇가지 규칙을 준수해야 합니다.
1. 감싸인 요소
컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸야합니다.
function App() {
return (
<h1>리액트 안녕!</h1>
<h2>잘 작동하니?</h2>
);
}
export default App;
이런 형태의 코드는 제대로 작동하지 않고 오류가 납니다. 요소 여러 개가 부모 요소 하나에 의하여 감싸져 있지 않기 때문에 오류가 발생했습니다.
이 오류는 다음과 같이 코드를 작성하여 해결할 수 있습니다.
function App() {
return (
<div>
<h1>리액트 안녕!</h1>
<h2>잘 작동하니?</h2>
</div>
);
}
export default App;
리액트 컴포넌트에서 요소 여러 개를 왜 하나의 요소로 꼭 감싸주어야 할까요? 그것은 Virtual DOM에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문입니다.
그런데 여기서 div 요소를 사용하고 싶지 않을 수도 있습니다. 그런 경우에는 리액트 v16 이상부터 도입된 Fragment라는 기능을 사용하면 됩니다.
import { Fragment } from 'react';
function App() {
return (
<Fragment>
<h1>리액트 안녕!</h1>
<h2>잘 작동하니?</h2>
</Fragment>
);
}
export default App;
코드 상단의 import 구문에서 react 모듈에 들어 있는 Fragment라는 컴포넌트를 추가로 불러옵니다.
Fragment는 다음과 같은 형태로도 표현할 수 있습니다.
function App() {
return (
<>
<h1>리액트 안녕!</h1>
</>
);
}
export default App;
2. 자바스크립트 표현
JSX 안에서는 자바스크립트 표현식을 쓸 수 있습니다. 자바스크립트 표현식을 작성하려면 JSX 내부에서 코드를 { }로 감싸면 됩니다.
function App() {
const name = '리액트'
return (
<>
<h1>{name} 안녕!</h1>
<h2>잘 작동하니?</h2>
</>
);
}
export default App;
3. If문 대신 조건부 연산자
JSX 내부의 자바스크립트 표현식에서 if문을 사용할 수는 없습니다. 하지만 조건에 따라 다른 내용을 렌더링해야 할 때는 JSX 밖에서 if 문을 사용하여 사전에 값을 설정하거나, { } 안에 조건부 연산자(=삼항연산자)를 사용하면 됩니다.
function App() {
const name = '리액트'
return (
<div>{name === '리액트' ? (<h1>{name} 안녕!</h1>) : (<h2>잘 작동하니?</h2>)}</div>
);
}
export default App;
4. AND 연산자(&&)를 사용한 조건부 렌더링
특정 조건을 만족할 때 내용을 보여주고, 만족하지 않을 때 아예 아무것도 렌더링 하지 않아야 하는 상황이 올 수 있습니다. 이럴 때도 조건부 연산자를 통해 구현할 수 있습니다.
function App() {
const name = '리액트';
return <div>{name === '리액트' ? <h1>리액트입니다.</h1> : null}</div>;
}
export default App;
위 코드와 같이 null을 렌더링하면 아무것도 보여주지 않습니다.
다음과 같이 && 연산자를 사용해 더 짧은 코드로 똑같이 작업을 할 수 있습니다.
function App() {
const name = '리액트';
return <div>{name === '리액트'&& <h1>리액트입니다.</h1>}</div>;
}
export default App;
5. undefined를 렌더링하지 않기
리액트 컴포넌트에서는 함수에서 undefined만 반환하여 렌더링하는 상황을 만들면 안됩니다.
예를 들어 다음과 같은 코드는 오류를 발생시킵니다.
import './App.css';
function App() {
const name = undefined;
return name;
}
export default App;
어떤 값이 undefined일 수도 있다면, OR(||)연산자를 사용하면 해당 값이 undefined일 때 사용할 값을 지정할 수 있으므로 간단하게 오류를 방지할 수 있습니다.
import './App.css';
function App() {
const name = undefined;
return name || '값이 undefined입니다.';
}
export default App;
반면 JSX 내부에서 undefined를 렌더링하는 것은 괜찮습니다.
import './App.css';
function App() {
const name = undefined;
return <div>{name || '리액트'}</div>;
}
export default App;
6. 인라인 스타일링
리액트에서 DOM 요소에 스타일을 적용할 때는 문자열 형태로 넣는 것이 아니라 객체 형태로 넣어 주어야 합니다.
스타일 이름 중에서 background-color처럼 - 문자가 포함되는 이름은 - 문자를 없애고 카멜 표기법으로 작성해야 합니다.
function App() {
const name = '리액트';
const style = {
backgroundColor: 'black',
color: 'aqua',
fontSize: '48px',
fontWeight: 'bold',
padding: 16 //단위를 생략하면 px로 지정됩니다.
}
return <div style={style}>{name}</div>
//style 객체를 미리 선언하지 않고 작성하는 방법
//<div style={{fontSize: '48px'}}>{name}</div>
}
export default App;
7. class 대신 className
HTML에서 CSS클래스를 사용할 때는 class라는 속성을 설정하지만, JSX에서는 class가 아닌 className으로 설정해 주어야 합니다.
8. 꼭 닫아야 하는 태그
HTML 코드는 태그를 닫지 않아도 코드가 문제없이 작동하지만, JSX에서는 태그를 닫지 않으면 오류가 발생합니다.
<input /> 처럼 태그 사이에 별도의 내용이 들어가지 않는 self-closing 태그로 작성할 수도 있습니다.
9. 주석
JSX에서 주석을 작성할 때는 {/* .... */}와 같은 형식으로 작성합니다.
그리고 아래와 같이 시작 태그를 여러줄로 작성할 때는 그 내부에서 // ... 과 같은 형태의 주석도 작성할 수 있습니다
function App() {
const name = '리액트';
return (
<>
{/* 일반적인 주석 */}
<div
className="react" //이런식으로 시작 태그를 여러 줄로 작성하게 된다면 주석을 작성할 수 있습니다.
>
{name}
</div>
</>
);
}
export default App;
참고 서적 : 리액트를 다루는 기술
'프론트엔드 > 리액트' 카테고리의 다른 글
[React] 리액트 - 4 (컴포넌트) (0) | 2023.12.14 |
---|---|
[React] 리액트 - 1 (기초 개념) (0) | 2023.12.11 |