리액트에서 흔히 많이 하는 실수를 알아보기 위해, 일단은 기초적인 JSX의 문법을 배워보자.
JSX가 바벨을 만나면 JS 코드로 트랜스파일링 되는데, 이를 코드로 보면
// JSX
ReactDOM.render(
<div id="msg">Hello World!</div>,
mountNode
)
// 이렇게 JS로 바뀐다.
ReactDOM.render(
React.createElement('div', { id: **'msg'** }, **'Hello World!'**),
mountNode
)
이렇게 된다.
중요한 점은 JSX에서 JS로 트랜스파일링되면서
들어가게 된다는 것이다. 즉, 이 둘의 자리에는 문이 올 수 없고 오직 값과 식만이 올 수 있다는 것.
여기까지 알아보고 한번 밑의 코드를 살펴보자.
// JSX. 값이 있어야 하는 자리에 문이 있다. **Unexpected "if"** 오류가 난다.
<div **id={if (condition) { 'msg' }}**>Hello World!</div>
// JS. 값이 있어야 하는 자리에 문이 있다. 오류가 난다.
React.createElement('div', {**id: if (condition) { 'msg' }**}, 'Hello World!')
// 삼항연산자는 값으로 귀결되는 식이다. 따라서 오류가 나지 않는다.
ReactDom.render(<div **id={condition ? 'msg' : null}**>Hello World!</div>, mountNode)
위의 코드처럼 이렇게 if문을 객체의 키의 값으로 넣을 수 있을까? 당연히 안 된다. 즉, 문을 값의 자리에 넣는 것은 불가능하다(Unexpected "if"
에러).
하지만 삼항 연산자의 경우에는 값의 자리에 올 수 있는데, 이는 식은 값으로 귀결되기 때문에 값의 자리에 삽입할 수 있는 것이다.
만약 if문과 같이 분기를 나누어 그 결과를 값에 할당하고 싶을 때는 **즉시실행함수(IIFE)**를 사용한다.
<p>
{(() => {
switch (this.state.color) {
case 'red':
return '#ff0000'
case 'green':
return '#00ff00'
case 'blue':
return '#0000ff'
default:
return '#ffffff'
}
})()}
</p>
앞서 말했듯이, 원래 html 태그 사이에는 값이나 식만이 올 수 있다. 위에 작성한 즉시실행함수는 swtich문을 돌면서 이에 해당하는 값을 결과로서 바로바로 뱉어내기 때문에 태그 사이에 올 수 있는 것이다. 약간의 꼼수랄까.
<p>{this.state.color || 'white'}</p>