[React]JSX와 JSX문법 이해하기 ep.01
JSX란?
JSX는 Javascript XML의 약자로, 리액트에서 사용되는 javascript의 확장 문법이다. JSX는 JavaScript 코드 안에서 XML 형태로 마크업을 작성할 수 있게 해준다.
이전 게시물과 이어지는 내용이니 참고하세요.
https://bbingbbong.tistory.com/9
[React] 리액트 시작하기, 설치하기 ep.00
리액트를 시작하기전, 먼저 리액트가 무엇인가 알아보고자 한다. 리액트란 ? 웹프레임 워크중 하나로, 자바스크립트에서 사용할 수 있는 라이브러리이다. 페이스북에서 효율적이고 편리한 UI를
bbingbbong.tistory.com
이전 게시물에서 리액트를 시작해 보았다.
리액트 시작하면, src 폴더의 App.js 파일을 살펴보겠다.
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
App.js 파일이 이와 같은 코드로 되어 있을 것이다.
구성들이 매우 Html과 비슷하지만, html이 아닌 JSX 라고한다.
JSX 문법
JSX는 편리하지만, 몇가지 규칙을 준수해야한다.
먼저, 부모 요소 하나로 항상 감싸야한다.
바로 실습에 옮겨 예를 들어 설명해보겠다.
실제로 이 규칙을 모른상태로 바로 시작했었는데..부모요소로 감싸야 된다는 오류가 떠서 이유도 모르고 그냥 따라했었다. 이유를 알게 되어서 참.. 기쁘다!!
function App() {
return (
<h1>리액트 시작! </h1>
);
}
export default App;
App.js 의 내용들을 지우고 이렇게 바꿔준다.
저장(Ctrl +s)을 하고 npm start를 입력하거나 이미 떠있는 리액트 페이지를 살펴보겠다.

아주 잘 작동 한것을 볼 수 있다. 그렇다면, 이렇게 다시 코드를 구성해보겠다.
function App() {
return (
<h1>리액트 시작! </h1>
<p>재미있는 리액트 ,,, ^^ </p>
);
}
export default App;
<p>태그를 이용해 한줄더 추가 해줬다.(김밥 한줄아님)

그렇다면... 이렇게 무시무시한 화면을 맞닥뜨리게 된다..!!
하지만 우리는 용감한 개발자이기 때문에 오류메세지를 확인하고, 고쳐줄 마음의 준비를한다...
Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?
이러한 에러를 마주했다..!!
번역을 해보자면 ~ JSX 요소는 tag로 감싸주어야한다는 뜻이다.
오류의 지시를 따라 코드를 다시 수정하였다.
function App() {
return (
<>
<h1>리액트 시작! </h1>
<p>재미있는 리액트 ,,, ^^ </p>
</>
);
}
export default App;
<h1>과 <p> 태그를 <>를 사용하여 감싸주었더니 오류가 생기지 않고 잘 작동하였다.

굿굿 !!
지금껏 이유를 모른채로 따라 써보기만 했는데, JSX의 기본적인 문법이란것을 알 수 있었다.
하지만 왜 <>일까?..
오류를 수정하면서 알게된 사실이지만 <div>태그도 가능하다.
<>를 쓰는 이유를 간략히 알아보겠다..
먼저, <div> 태그를 사용하여도 문제없다.
하지만 리액트 v16이상부터 도입된 <Fragment>라는 기능이 있기때문에 굳이 div태그를 사용하지 않아도 된다.
<Fragment>태그는 <>로 생략 할 수 있다. 즉.. <>는 Fragment태그 라는것이다.
아마도 버전 문제 같은데, 현재 App.js에서는 굳이 import React를 해주지 않아도 잘 작동하고 있다. 현재 사용한 Fragment 태그도 사용하려면
import {React, Fragment} from 'react';
위코드를 상단에 작성해주어야 한다.
현재 파일에서는 작성하지 않아도 오류가 생기지 않지만, 앞으로 계속 개발을 하다보면 이부분이 있어야 할 때가 있기 때문에 반드시 기억해두자.
자바스크립트 표현
JSX는 자바스크립트 언어는 아니지만, javascript 문법을 사용할 수 있다.
어떻게 사용하는지 알아보도록하자.
function App() {
const name = '리액트';
return (
<>
<h1>{name} 시작! </h1>
<p>재미있는 리액트 ,,, ^^ </p>
</>
);
}
export default App;
이렇게 Javascript에서 변수 선언을 했던것처럼, return전에 변수를 만들어주고, { }를 통해서 사용할 수 있다.
결과는 ..

변수가 잘 들어간것을 확인할 수 있다.
If문 대신 조건부 연산자
JSX 내부의 javascript 표현식에서는 if문을 사용할 수 없다고 한다.
하지만 개발을 하다보면 필요할 때가 있을것이다.. 따라서 If문(조건식)사용 방법도 알아보겠다.
사실 If문.. 은 사용할 수 없고, 대신 조건부 연산자를 사용하여야 한다.
조건부 연산자에 대해 짧게 알아보자면,
A>B ? A:B
이것이 조건부 연산자인데, A>B가 참이면 A, 거짓이면 B라는 뜻이다.
한번 적용해보겠다.
import {React, Fragment} from 'react';
function App() {
const name = '리액트';
return (
<>
{name === '리액트' ? (
<h1>리액트입니다.~</h1>
) : (
<h1>리액트가 아닙니다.~</h1>
)}
</>
);
}
export default App;
이렇게 바꿔 보았다.
결과는?

const name 을 앞에서 '리액트' 라고 정의해주었기때문에, 조건식이 참이되어 이와 같은결과가 나타났다.
그렇다면 거짓은 어떻게 되는지도 짧게 알아보겠다.
import {React, Fragment} from 'react';
function App() {
const name = '리액토';
return (
<>
{name === '리액트' ? (
<h1>리액트입니다.~</h1>
) : (
<h1>리액트가 아닙니다.~</h1>
)}
</>
);
}
export default App;
눈치를 챘을지 모르겠지만, const name = '리액토' 로 수정하였다.
결과는

아주 똑부러진다.
이런식으로 조건부 연산자를 잘 활용해보도록 하자.
AND 연산자(&&)를 사용한 조건부 렌더링
특정조건을 만족할때는 내용을 보여주고, 만족하지 않을때는 아무것도 렌더링 하지 않는 상황에서는 어떻게 하면 좋을지 알아보자.
import {React, Fragment} from 'react';
function App() {
const name = '리액토';
return (
<>
{name === '리액트' ? (
<h1>리액트입니다.~</h1>
) : null}
</>
);
}
export default App;
이런식으로 False일시에는 null 을 입력해주면
빈화면이 나온다. (아무것도 렌더링 되지 않음.)
이 코드보다 더 간략하게 AND 연산자를 사용하여 나타낼 수 있다.
import {React, Fragment} from 'react';
function App() {
const name = '리액토';
return (
<>
{name === '리액트' &&
<h1>리액트입니다.~</h1>}
</>
);
}
export default App;
이렇게 AND 연산자를 사용 하면 같은결과를 볼 수 있다.
코드의 길이가 짧아지기 때문에 손에 익히기만 한다면 요긴하게 쓰일 것 같다.
단, 주의해야 할점은 변수를 0으로 정의하였을때, false로 인식하기 때문에 0이 출력된다.
컴퓨터는 0은 0(거짓), 0이외의 정수는 1(참)으로 인식하는 특성 때문 인것 같다.
import {React, Fragment} from 'react';
function App() {
const name = 1;
return (
name && <><h1>리액트 입니다.</h1> </>
);
}
export default App;
걱정하지 않아도 될것같은점은 . . . 이런구조의 코드를 안쓸것같다. 하지만 예외상황은 언제나.. 알아두는 것이 미래의 나에게 좋다.

undefined를 렌더링 하지 않기
또 주의해야 할 점이 있다.
'undefined를 렌더링 하지 않기'이다. 사실 undefined라는 표현을 잘 써본적이 없어서.. 좀 안와닿는다. 이런 상황이 언제 주로 발생하는지 파악되지 않기 때문이다.. 때문에 나처럼 리액트에 입문하는 사람들은 잘 안와닿을것같다.
하지만 멋진 개발자가 될 우리기에, 미래를 위해서라도 간략하게 알아보고 넘어 가보겠다.
먼저 undefined는 언제 사용 되는 것인지 알아보겠다.
null과 undefined의 차이는
null : 값이 없음.
undefined : 변수가 선언되었지만 아무것도 할당되지 않은상태
라고 한다. 실제로 실습을 해보지 않으면 좀처럼 안와닿을 것 같기 때문에.. 실습을 통해 알아보겠다.
undefind를 반환해야 하는 경우가 종종 있다보다. 그렇기 때문에 렌더링을 하지 않도록 주의해야 한다는 것이 요점이다.
실습을 통해 알아보려고 하는데...
function App() {
const num = undefined;
return num;
}
export default App;
이렇게.. 하면 오류가 뜨는것이 정상인데 ... 그냥 아무것도 뜨지 않고 오류도 뜨지 않는다.
아무것도 뜨지 않는이유는 undefined가 렌더링 됐기 때문.. 같다.. 따라서 제대로 렌더링이 된것같다.
책에서는 오류가 뜬다고 나와있는데.. 아마도 리액트 버전이 업그레이드 되면서 해결된 상황인것 같다..
찾아보았지만 ㅠㅠ 오류가 안나는 이유에 대한 이야기는 없기 때문에.. 넘어가도록 해보자..!!
결론은 undefined를 렌더링 해도 된다(?)
값이 undefined 일때 화면을 띄우는 법을 알아보면서 넘어가보도록 하겠다.
function App() {
const num = undefined;
return (
<>
{num || '리액트입니당'}
</>
)
}
export default App;
이렇게 작성한다면, num이 undefined 됐을때,

이런 화면을 띄운다는것을 알아 두자.
function App() {
const num = 1;
return (
<>
{num || '리액트입니당'}
</>
)
}
export default App;
값이 undefined가 아닐때에는

이런 화면 이다.
인라인 스타일링
지금부터는 리액트안에서 스타일을 적용 시키는 방법을 알아보겠다.
중요한점은 Html Css 문법이랑 조금씩 다른 부분이 있다는것이다.
바로 실습을 통해 알아보자.
import {React, Fragment} from 'react';
function App() {
const name = 'React 스타일링하기~';
return (
<div
style = {{
// background-color는 backgroundColor 처럼 -가 사라지고 카멜표기법으로 사용해야한다.
backgroundColor: 'pink',
color: 'aqua',
fontSize : '12px',
fontWeight : 'bold',
padding : 16
}}
>
{name}
</div>
)
}
export default App;
스타일링을 적용해보았다..
혹시 나의 이전 코드와 달라진점을 눈치 챈사람이 있을까?
이전에는 fragment 태그를 사용하였다. <>
하지만 지금은 <div>태그를 사용했다. 앞서 Fragment를 설명할때, div를 사용해도 상관없다고 설명한적이 있다.
하지만 이건 반대로 div를 사용하지 않고 <>를 사용하면 적용이 안된다..!!
매우 중요한 정보인데 모르고 넘어갈 뻔한게 소름이 돋는다.
아무튼 결과 화면은 이렇다..

너무 귀엽고 맘에드는군.. 여기서 실험해보고 싶은 마음이 들어서. <>의 정식 사용법인 <Fragment>를 사용해보았다.
webpack compiled successfully
라는 문구가 떴지만!

스타일링이 적용되지 않은것을 확인할 수 있었다.
꼭 div태그를 사용해서 스타일링 하도록하자.
이번엔 css파일을 통해서 스타일링을 해보도록 하겠다.
import {React, Fragment} from 'react';
import './App.css';
function App() {
const name = 'React 스타일링하기~';
return (
<Fragment className = "react">
{name}
</Fragment>
)
}
export default App;
JSX에서 주의해야할 또다른 사항은 class 가 아닌 className을 사용한다는점이다. 혼용하지 않도록 주의하자.
App.js 파일을 다음과 같이 수정해주고, 제일 위해 import './App.css'; 를 반드시 추가 해주어야 한다.
그리고 소름돋는 두번째 발견.. 여기서도 <Fragment>태그는 사용할 수 없다.
생각을 해봤는데, <div>태그와 <Fragment>는 자식요소를 감싼다는 점에서는 비슷한점을 같고있지만,
기능은 분명하게 다르고, className을 지정해줄때나, 스타일 요소들을 추가할때는 fragment는 div처럼 기능하지 못하는 것같다.
좀더 정확하게 하기 위하여 찾아보았는데, div는 HTML에서 사용되는 특정 요소로서 블록수준의 그룹화를 하는 기능이고,
fragment는 요소들을 감싸주기만 하는 기능만 한다.
fragment기능이 react 16부터 생겨난 이유는 쓸데없는 요소추가를 막기 위해서라고 한다.
아무튼 다시 div태그를 사용하여 스타일을 적용해 보겠다.
import {React, Fragment} from 'react';
import './App.css';
function App() {
const name = 'React 스타일링하기~';
return (
<div className = "react">
{name}
</div>
)
}
export default App;
자 다시 div태그를 사용해보았다.
그리고 App.css 파일은 모두 지워주고 다음과 같이 채워주었다.
.react{
background : pink;;
color : aqua;
font-size:48px;
font-weight:bold;
padding:16px;
}
결과를 확인해보자.

너무 귀엽다!!
css는 귀찮지만 재밌다. ㅎㅎ
아무튼 여기서 스타일링 적용시키는 방법을 마무리 짓도록 하겠다.
출처: 리액트를 다루는 기술 - 김민준