JSX 활용
JSX는 JavaScript 표현식(expression) (opens new window)을 중괄호({}
)로 묶어 데이터를 바인딩(Binding) 한다. 쉽게 말해 HTML 코드에서 데이터를 빼내 변수에 등록한 후, 변수를 HTML 코드에 바인딩(binding)할 수 있다는 말이다.
상태가 변경되면 JSX 요소가 반환되고 반환된 요소를 렌더링 한다.
1. 데이터 바인딩 하기
Data는 곧 상태(State)가 된다. 해당 데이터를 요소 내부에 바인딩 시키는 작업을 해보자
const app = (
<div className="app">
<h1 className="app-title">
<span lang="en"></span>
</h1>
</div>
)
위의 app
의 요소 내부의 콘텐츠를 분리시키는 작업을 한다.
// Data === State
const state = {
appClassName: 'app',
apptitleClassName: 'app-title',
appHeadlineContents: ['React', '앱'],
}
분리한 데이터를 요소 내부에 바인딩 할 때 아래와 같이 중괄호({}
, Curly Brackets)를 사용해서 바인딩 할 수 있다. 이 방식을 사용하면 동적으로 콘텐츠 변경이 가능하다.
const app = (
<div className={state.appClassName}>
<h1 className={state.appTitleClassName}>
<span lang="en">{state.appHeadlineContents[0]}</span>{' '}
{state.appHeadlineContents[1]}
</h1>
</div>
)
1-(1) 결과
import React from 'react'
import ReactDOM from 'react-dom'
// Data === State
const state = {
appClassName: 'app',
appTitleClassName: 'app-title',
appHeadlineContents: ['React', '앱'],
}
const app = (
<div className={state.appClassName}>
<h1 className={state.appTitleClassName}>
<span lang="en">{state.appHeadlineContents[0]}</span>{' '}
{state.appHeadlineContents[1]}
</h1>
</div>
)
ReactDOM.render(app, document.getElementById('root'))

2. 콘텐츠 컴파일
JSX 코드의 {}
는 JavaScript 표현식의 연산된 결과 값을 처리하여 콘텐츠를 컴파일 한다. 아래의 데이터를 요소에 바인딩 해보자
const bindingContents = {
number: 909,
string: '콘텐츠 바인딩',
howCanIuseJSexpressionInsideJSX() {
return 'JavaScript 식(Expression)은 항상 값을 반환함으로 {}안에 바인딩이 가능하다'
},
}
{}
내부에서 + 1
연산자를 사용할 수 있고 템플릿 리터럴을 사용할 수도 있다.
const app = (
<div className="app">
{bindingContents.number + 1} {`${bindingContents.string} hi!!`}
</div>
)
또는 아래와 같은 방식으로도 자바 스크립트 식을 바인딩 할 수 있다.
const app = (
<div className="app">{bindingContents.howCanIuseJSexpressionInsideJSX()}</div>
)
replace()
메서드를 사용해서 공백을 -
기호로 변경할 수 있다.
const app = (
<div className="app">
{bindingContents.howCanIuseJSexpressionInsideJSX().replace(/\s/g, ' - ')}
</div>
)
단, 식이 아닌 문은 사용이 불가능하다 (오류 발생)
const app = (
<div className="app">
{if (true) {'hi'} else {'oops'}}
</div>
)

2-(1) 결과
import React from 'react'
import ReactDOM from 'react-dom'
const bindingContents = {
number: 909,
string: '콘텐츠 바인딩',
howCanIuseJSexpressionInsideJSX() {
return 'JavaScript 식(Expression)은 항상 값을 반환함으로 {}안에 바인딩이 가능하다'
},
}
const app = (
<div className="app">
{bindingContents.number + 1} {`${bindingContents.string} hi!!`}
<div>{bindingContents.howCanIuseJSexpressionInsideJSX()}</div>
</div>
)
ReactDOM.render(app, document.getElementById('root'))
2.1 정리
2.1-(1) 문자 값
<h1>{`${headline}(${abbrs.jsx})`}</h1>
2.1-(2) 숫자 값
<span>{number % 4}</span>
2.1-(3) 함수 (또는 메서드) 결과 값
<p>{formatCount()}</p>
3. 속성 컴파일
속성 값으로 큰 따옴표(""
) 대신 중괄호({}
)로 묶어 JavaScript 표현식을 사용해 동적으로 속성에 데이터를 바인딩할 수 있다.
const app = <abbr title={abbrs.jsx}>{headline}</abbr>
3-(1) 스타일 속성 (인라인)
스타일 코드를 JavaScript 객체({}
)로 표기하여 사용한다.
const app = <li style={{ color: '#ea6666', fontWeight: 900 }}>스타일 속성(인라인)</li>
3-(2) 스타일 속성 (객체)
스타일 코드를 설정한 객체를 변수에 분리하여 처리할 수도 있다.
const liStyle = { color: '#ea6666', fontWeight: 100 }
const app = <li style={liStyle}>스타일 속성(객체)</li>
3-(3) 클래스 속성
CSS 클래스 속성을 React 요소에 설정하고자 한다면? JavaScript 예약어 class
대신 className
을 사용해야 한다.
const app = <li className="bordered rounded">클래스 속성</li>
3-(4) 클래스 속성 (동적 처리)
동적으로 CSS 클래스 이름을 변경해야 할 경우, 아래와 같이 {}
를 사용해 처리합니다.
const borderColor = 'blue' / 'red', 'green'
const app = <li className={`rounded bordered bordered-${borderColor}`}>
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
const state = {
appClass: 'app',
}
const borderColor = 'blue'
const liStyle = { color: '#ea6666', fontWeight: 100 }
const app = (
<div className={state.appClass}>
<h1 className="a11y-hidden">속성 컴파일</h1>
<ul>
{/* 직접 스타일 추가 */}
<li style={{ color: '#ea6666', fontWeight: 900 }}>스타일 속성(인라인)</li>
{/* 영역 외부에서 설정한 스타일 추가 */}
<li style={liStyle}>스타일 속성(객체)</li>
<li className="bordered rounded">클래스 속성</li>
<li className={`rounded bordered bordered-${borderColor}`}>
클래스 속성(동적 처리)
</li>
</ul>
</div>
)
ReactDOM.render(app, document.getElementById('root'))
4. 조건부 렌더링
4-(1) if 문
아래와 같은 조건문을 만들어 요소에 바인딩 할 수 있다. Math.random()
메서드를 사용해서 값이 랜덤으로 나올 수 있도록 추가적으로 설정할 수 있다.
조건문
// 조건부 처리할 함수
function conditionaRendering(usingList = false) {
// 조건문 if, switch
if (usingList) {
return (
<ul>
<li>조건 문 사용</li>
<li>조건 식 (3항식, 논리곱/합 연산자) 활용</li>
</ul>
)
} else {
return <p>"조건 문 활용" 또는 "조건 식 (3항식, 논리곱/합 연산자) 활용"</p>
}
}
function randomBoolean() {
return Math.random() < 0.5 ? true : false
}
데이터 바인딩
이때도 마찬가지로 중괄호({}
)를 사용해서 값을 넣어준다.
const app = (
<div className="app">
<h1>조건부 렌더링</h1>
{conditionaRendering(randomBoolean())}
</div>
)
4-(2) switch 문
조건문
// 조건부 처리할 함수
function conditionaRendering(count = 0) {
// 조건문 switch
switch (count) {
case 1:
return (
<ul>
<li>조건 문 사용</li>
<li>조건 식 (3항식, 논리곱/합 연산자) 활용</li>
</ul>
)
break
case 2:
return <p>"조건 문 활용" 또는 "조건 식 (3항식, 논리곱/합 연산자) 활용"</p>
break
default:
return (
<p>
React의 <abbr title="JavaScript Syntax eXtension">JSX</abbr>는
JavaScript 객체(React 요소)를 반환합니다.
</p>
)
}
}
// 숫자를 전달하면 항상 0, 1, 2 중에 하나인 값을 반환하도록 만든다.
function randomCount(number) {
return number % 3
}
데이터 바인딩
const app = (
<div className="app">
<h1>조건부 렌더링</h1>
{conditionaRendering(randomCount(Math.floor(100 * Math.random())))}
</div>
)

4-(3) 3항식
// 목록 또는 단락을 조건부 렌더링 하기 위한 조건 상태
let usingList = true
let usingBorderColor = true
const app = (
<div className="app">
<h1>조건부 렌더링</h1>
{/* JSX 내부의 주석 처리 */}
{/* 조건에 따라 목록을 렌더링 */}
{usingList ? (
<ul>
<li>조건 문 활용</li>
<li
className={`bordered ${
usingBorderColor ? 'bordered-red' : ''
}`.trim()}
>
조건 식 (3항식, 논리곱/합 연산자) 활용
</li>
</ul>
) : (
<p>"조건 문 활용" 또는 "조건 식 (3항식, 논리곱/합 연산자) 활용"</p>
)}
</div>
)
4-(4) 논리 연산자
// 목록 또는 단락을 조건부 렌더링 하기 위한 조건 상태
let usingList = true
let usingBorderColor = true
const a11y = {
hiddenClass: 'a11y-hidden',
}
const app = (
<div className="app">
<h1 className={a11y.hiddenClass || null}>조건부 렌더링</h1>
{/* JSX 내부의 주석 처리 */}
{/* 조건에 따라 목록을 렌더링 */}
{usingList ? (
<ul>
<li>조건 문 활용</li>
<li
className={`bordered ${
usingBorderColor ? 'bordered-red' : ''
}`.trim()}
>
조건 식 (3항식, 논리곱/합 연산자) 활용
</li>
</ul>
) : (
<p>"조건 문 활용" 또는 "조건 식 (3항식, 논리곱/합 연산자) 활용"</p>
)}
</div>
)
4.1 코드 정리
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
// 조건부 처리할 함수
function conditionaRendering(usingList = false) {
// 조건문 if, switch
if (usingList) {
return (
<ul>
<li>조건 문 사용</li>
<li>조건 식 (3항식, 논리곱/합 연산자) 활용</li>
</ul>
)
} else {
return <p>"조건 문 활용" 또는 "조건 식 (3항식, 논리곱/합 연산자) 활용"</p>
}
}
function randomBoolean() {
return Math.random() < 0.5 ? true : false
}
const app = (
<div className="app">
<h1>조건부 렌더링</h1>
{conditionaRendering(randomBoolean())}
</div>
)
ReactDOM.render(app, document.getElementById('root'))
5. 리스트 렌더링
5-(1) 들어가기 전
리스트를 레더링하여 JSX 요소에 데이터를 바인딩 할 때 아래와 같이 배열 데이터를 순환하여 사용한다.

forEach() 메서드는 왜 사용하지 않는가?
사용을 못하는 것은 아니지만forEach()
메서드는 값을 반환하지 않기 때문에 JSX에서 사용하기에 적합하지 않다.

실습 (1)
아 위에서 먼저 콘솔 패드에서 map()
메서드를 사용해서 배열 데이터를 바인딩 한 것처럼 JSX에서도 아래와 같이 배열 데이터를 요소에 바인딩 했다.
사용 방법은 이전의 데이터 바인딩 방법과 똑 같다. {}
로 묶어주고 그 안에서 map()
메서드를 사용하고 JSX 요소를 작성해서 순환되는 데이터가 어디에 들어가야 할지 설정한다.
const numbers = [500, 50, 5, 0.5]
const app = (
<div className="app">
<h1>리스트 렌더링</h1>
<ul>
{numbers.map((n) => (
<li>{n * 2}</li>
))}
</ul>
</div>
)
React에서는 리스트를 렌더링 할 때, 각 아이템을 구분 할 수 있도록 고유한 key 값을 부여해야한다. 오류를 해결하기 위해 고유한 식별자(id) 값을 설정하자
아래와 같이 index
를 key
값으로 해서 각 아이템의 식별자로 만들었다. (오류 해결)
const app = (
<div className="app">
<h1>리스트 렌더링</h1>
<ul>
{numbers.map((n, i) => (
<li key={i}>{n * 2}</li>
))}
</ul>
</div>
)
실습 (2)
실습(1)과 같은 간단한 예제 말고 복잡한 배열 데이터 바인딩 해보자 아래의 강사의 정보를 담고 있는 배열 데이터가 있다.
const FEML_lecturers = [
{
id: 'lecturer-az081871',
name: '김데레사',
module: 'A',
facebook: 'http://facebook.com/seulbinim',
image: 'http://yamoo9.github.io/images/photo-deresa@2x.png',
},
{
id: 'lecturer-az081872',
name: '야무',
module: 'B, C',
facebook: 'http://facebook.com/yamoo9',
image: 'http://yamoo9.github.io/images/photo-yamoo9@2x.png',
},
]
5-(2) 데이터 바인딩
const app = (
<div className="app" role="main" aria-labelledby="main-title">
<h1 id="main-title">Front-End Masters League 강사진</h1>
<ul className="lecturers">
{FEML_lecturers.map((lecturer) => (
<li className="lecturers" key={lecturer.id}>
<a href={lecturer.facebook} rel="noreferer nopener">
<figure className="lecturer-info">
<img src={lecturer.image} alt="" className="lecturer-photo" />
<figcaption>
{lecturer.module} 모듈을 담당 할 {lecturer.name} 강사 Facebook
바로가기
</figcaption>
</figure>
</a>
</li>
))}
</ul>
</div>
)
5.1 리스트 조건부 처리
5.1-(1) 정리
배열 데이터를 순환 처리 해서 사용하도록 map()
메서드를 사용하고 각 아이템을 데이터 바인딩을 한다. 그리고 리스트에는 고유한 key를 가지고 있어야만 오류가 표시되지 않는다.
6. 주의할 점
6-(1) 속성 이름은 camelCase 표기법으로 사용하기
JSX는 HTML이 아닌 JavaScript 식이다. 그래서 React DOM은 HTML 표준 속성 이름 중 일부는 그대로 이름을 사용할 수 없다. 예를 들어 class
는 className
으로, tabindex
는 tabIndex
로 사용해야 한다. 즉, 음절이 2개 이상인 경우 camelCase로 표기하기!
단, 접근성 속성은 그대로 사용해도 괜찮다.
aria-*
접두사가 붙거나, role
과 같은 접근성 관련 속성은 기존에 HTML에서 사용하던 그래도 사용한다.
const app = (
<div className="app" role="main" aria-labelledby="main-title">
<h1 id="main-title">Front-End Masters League 강사진</h1>
</ul>
</div>
6-(2) 콘텐츠가 없는 요소는 항상 닫아야 한다.
JSX는 XML 문법에 따라 콘텐츠가 없는 빈 요소(empty element)는 반드시 닫아(/>
) 줘야 한다. (예: <img/>
, <br/>
, <area/>
, <meta/>
, <link/>
등)
6-(3) 기본적으로 루트 요소는 하나만 사용한다.
root 요소 <div>
위에 root 요소를 하나 더 생성하니 오류가 발생한다.

<div>
요소로 감싸줘서 root 요소가 하나만 있을 수 있도록 해야한다. (단, 이 경우는 의미없는 요소를 사용했기 때문에 시멘틱 마크업이라고 할 수 없다.)

또는 <React.Fragment>
요소를 사용해서 랩핑할 수 있다. (단, React를 불러와야 사용할 수 있다.)
const app = (
<React.Fragment>
<header>앱 헤더</header>
<div className="app" role="main" aria-labelledby="main-title">
<h1 id="main-title">Front-End Masters League 강사진</h1>
<ul className="lecturers">{**}</ul>
</div>
</React.Fragment>
)
<React.Fragment>
를 <></>
로 작성해줘도 적용된다. <React.Fragment>
의 별칭 같은 거라고 생각면 좋다.
const app = (
<>
<div className="app"></div>
<h1>조건부 렌더링</h1>]
</>
)
Last updated
Was this helpful?