View
JSX란?
JavaScript XML의 줄임말로 문자열도 아니고 HTML도 아니다. 리액트에서 UI를 구성할 때 사용하는 문법으로 JavaScript를 확장한 문법이다. JSX는 JavaScript가 확장된 문법이지만 브라우저가 바로 실행할 수 있는 JavaScript 코드가 아니므로 브라우저가 이해할 수 있는 JavaScript 코드로 변환을 해주어야 한다. 이때 이용하는 것이 바로 “Babel”이다. Babel은 JSX를 브라우저가 이해할 수 있는 JavaScript로 컴파일 후 브라우저가 읽고 화면에 렌더링한다.
JSX 사용하기
// 하나의 태그를 return 해주면 된다.
function App() {
return (<h1>Hello World!</h1>)
}
// 혹은
const element = <h1> Hello, world!</h1>; // element 생성
JSX에서 JavaScript 코드를 사용하라면 꼭 {}를 사용해야 한다.
// JSX 중괄호 안에는 JavaScript 표현식을 넣을 수 있다.
function App() {
const name = 'James'
return (<h1>Hello {name}!</h1>) // Hello James!
}
JSX도 표현식이다. 컴파일이 끝나면 JSX 표현식이 정규 JavaScript 함수 호출이 되고 JavaScript 객체로 인식된다. 즉, JSX를 if 구문 및 for 루프 안에 사용하고, 변수에 할당하고, 인자로서 받아들이고, 함수로부터 반환할 수 있다.
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
리액트에서 JSX를 사용하는 것은 필수가 아니지만 대부분 JSX를 사용해 UI를 마크업한다.
JSX 없이 JS에 직접 마크업
return React.createElement(
"h1", null, `Hello, ${formatName(user)}!`
)
JSX 사용
return <div className="hello">Hello, {formatName(user)}!</h1>
한 눈에 봐도 JS에 마크업하는 것 보다 HTML 문법을 이용해 작성이 가능한 JSX가 익숙하고 이해하기 쉬우므로 가독성도 좋고 복잡해 보이지도 않는다. 이처럼 리액트에서는 JSX를 사용하면 CSS, HTML, Javascript 3개의 파일이 필요했던 것이 JavaScript 만으로 마크업 형태의 코드를 작성하여 DOM에 배치할 수 있다.
JSX로 자식 정의
JSX 태그는 자식을 포함할 수 있다. 만약 자식 태그가 없다면 XML처럼 /> 를 이용해 바로 닫아주어야 한다.
// 자식 태그가 없을 경우 `/>`를 이용해 닫아주어야 한다.
const element = <img src={user.avatarUrl}/>;
// 자식을 포함하는 경우
const element = {
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
}
JSX는 주입 공격을 방지한다.
JSX에 사용자 입력을 삽입하는 것은 안전하다고 한다.
const title = response.potentiallyMaliciousInput;
const element = <h1>{title}</h1>;
기본적으로 ReactDOM은 JSX에 삽입된 모든 값을 렌더링하기 전에 이스케이프하므로 애플리케이션에서 명시적으로 작성되지 않은 내용은 주입되지 않는다. 모든 항목은 렌더링 되기 전에 문자열로 반환된다. 이런 특성으로 XSS(cross-site-scriptiong) 공격을 방지할 수 있다.
JSX는 객체를 표현한다.
Babel은 JSX를 React.createElement()호출로 컴파일한다.
// JSX
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
// Babel이 JSX 코드를 JavaScript 코드로 변환
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
정리 - JSX 규칙
- 꼭 하나의 태그만 반환해야 한다.
// error!
function App() {
return (
<h1>Hello!</h1>
<h2>Hello!</h2>
)
}
// 반드시 부모 태그에 감싸서 하나의 태그만 반환해야 함, 부모 태그가 없을 경우 `<></>` 사용해서 반환
function App() {
return (
<>
<h1>Hello!</h1>
<h2>Hello!</h2>
</>
)
}
- JSX안 내부에서 css의 class를 사용하려면 `className` 을 사용한다.
// React에서는 이를 html 클래스 속성 대신 자바스크립트 클래스로 받아들이기 때문에 주의해야 한다.
function App() {
return (
<>
<h1 className='hello'>Hello!</h1>
<h2>Hello!</h2>
</>
)
}
JSX에서는 className뿐만 아니라 태그 속성의 이름 즉, 프로퍼티의 이름은 카멜케이스(cameCase)로 작성해야 된다. 왜 카멜케이스로 작성하는 것일까? JSX는 결국 자바스크립트 코드로 변환되어 사용되며 JSX로 작성된 속성은 JavaScript 객체의 키가 된다. 자바스크립트의 경우 변수 이름을 명명할 때 - 과 class 와 같은 예약어사용할 수 없다. 따라서 class를 작성할 때는 className을 사용하며, 다른 css의 속성 stroke-width 도 strokeWidth로 작성합니다. 이러한 이유로 리액트에서는 HTML, SVG의 속성값들을 카멜케이스로 작성합니다.
- JSX에서 JavaScript를 쓰고자 한다면, 꼭 중괄호(`{}`)를 사용해야 한다.
// 중괄호를 사용하지 않으면 일반 텍스트로 인식한다.
function App() {
const name = 'Josh Perez';
return (
<div>
Hello, {name}
</div>
);
}
- React 엘리먼트가 JSX로 작성되면 "대문자"로 시작해야 합니다. 소문자로 시작하게 되면 일반적인 HTML 엘리먼트로 인식을 하게 된다.
// 대문자로 작성된 JSX 컴포넌트를 따로 사용자 정의 컴포넌트라고 한다.
function Hello() {
return <div>Hello!</div>
}
function HelloWorld() {
return <Hello />;
}
- 조건부 렌더링에는 삼항 연산자를 사용한다.
<div>
{
(1+1 === 2) ? (<p>정답</p>) : (<p>탈락</p>)
}
</div>
- 여러 개의 HTMl 엘리먼트를 표시할 때, map() 함수를 이용
function App() {
const list = ['우유', '딸기', '바나나', '요거트'];
return (
<>
<ul>
{ list.map((item) => (<li>{item}</li>))}
</ul>
</>
)
}
[참고 사이트]
'Language > ReactJS' 카테고리의 다른 글
[React] Context API 톺아보기 (1) | 2023.09.02 |
---|---|
[React] 상태 관리 라이브러리의 필요성 - Redux (1) | 2023.04.24 |
[React] Context API - useContext (2) | 2023.04.17 |
[React] 컴포넌트 (0) | 2023.04.05 |
[React] 안녕 CRA, 안녕 Vite (0) | 2023.03.28 |