지금까지 리액트의 핵심이라고 할 수 있는 컴포넌트의 개념을 살펴보았고, 첫 번째 컴포넌트도 만들었습니다. 이번 절에서는 컴포넌트를 만들 때 사용하는 JSX 문법을 자세히 살펴보겠습니다.
JSX란
리액트에서 컴포넌트는 자바스크립트 함수로 만드는데, 특이하게도 이 함수는 HTML 값을 반환합니다. 이렇듯 자바스크립트와 HTML 태그를 섞어 사용하는 문법을 JSX(자바스크립트 XML)라고 합니다. JSX는 자바스크립트의 확장 문법입니다.
JSX는 공식 자바스크립트 문법은 아닙니다. 그러나 JSX는 대다수 리액트 개발자가 사용하는 문법이며, 리액트 공식 문서의 예제로도 사용합니다. 심지어 리액트 개발팀 또한 JSX 문법의 사용을 적극 권장하고 있습니다.
JSX 문법을 이용하면 HTML 태그에서 자바스크립트의 표현식을 직접 사용할 수 있습니다. 비주얼 스튜디오 코드에서 component 폴더의 Body.js를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...① 상수 number를 선언하고 값 1을 저장합니다. ② 상수 number의 값을 <h2> 태그로 감싸 렌더링합니다. 이때 상수 number가 자바스크립트 표현식 이라는 걸 표현하기 위 해 중괄호{}
를 사용합니다.
Body.js를 수정했다면 저장하고 페이지에서 상수 number 값을 잘 렌더링하
는지 확인합니다.

상수 number에 저장한 값 1을 잘 렌더링하고 있습니다.
JSX와 자바스크립트 표현식
표현식이란 값으로 평가되는 식입니다. 즉,
10 + 20
같은 식은 결국 30으로 평가되기 때문에 표현식이라고 합니다. JSX는 자바스크립트 표현식을 HTML 태그와 함께 사용할 수 있어 가독성 있는 코드를 작성할 수 있습니다.그럼 JSX에서 자주 사용하는 표현식을 하나씩 살펴보겠습니다.
산술 표현식
산술 표현식이란 숫자로 표현되는 식을 말합니다. component 폴더의 Body.js를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...① numA + numb는 두 변수를 더한 연산식입니다. 이 연산식은 숫자로 평가되는 산술 표현식 이므로 JSX 문법과 함께 사용합니다.
결과를 확인하면 1 + 2 를 계산한 값 3을 렌더링합니다.

문자열 표현식
문자열 표현식이란 문자열 또는 문자열로 평가되는 식을 말합니다. component 폴더의 Body.js를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...① strA + strB는 문자열과 문자열을 이어 붙입니다. 문자열을 반환하는 표현식이므로 JSX 문법과 함께 사용합니다.
결과를 확인하면 안녕리액트를 렌더링합니다.

논리 표현식
논리 표현식이란 참이나 거짓으로 평가되는 식입니다. component 폴더의 Body.js를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...① boolA || boolB는 참 또는 거짓인 불리언 값을 반환하는 표현식으로 JSX 문법과 함께 사용 합니다.
결과를 확인하면 다음 그림과 같습니다.

아무런 결과도 렌더링하지 않았지만 오류는 아닙니다.
논리 표현식의 결과인 불리언 값은 숫자나 문자열과 달리 페이지에 렌더링되
지 않습니다. 만일 불리언 값을 페이지에 렌더링하고 싶다면, 다음과 같이 형 변환 함수를 이용해 문자열로 바꿔 주어야 합니다.
코드를 불러오는 중 입니다 ...① String()은 숫자나 불리언 값을 문자열로 변환하는 형 변환 함수로, 자바스크립트에서 기본 으로 제공합니다.

사용할 수 없는 값
JSX는 값을 반환하는 자바스크립트 표현식을 사용할 수 있습니다. 그러나 모든 값을 사용할 수 있는 것은 아닙니다. 원시 자료형에 해당하는 숫자, 문자열, 불리언, null, undefined를 제외한 값을 사용하면 오류가 발생합니다.
Body 컴포넌트에서 객체 자료형을 JSX 문법으로 사용해 보겠습니다. component 폴더의 Body.js를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...객체 자료형 값을 반환하는 표현식을 JSX 문법으로 작성한 다음, 저장하면 페이지 에는 아무것도 나타나지 않습니다. 개발자 도구의 콘솔을 열어 보면 오류가 발생했다는 것을 알 수 있습니다.

콘솔의 내용을 살펴보면 “Object are not valid as a React Child”라는 메시지를 발견 할 수 있는데, “객체는 리액트의 자식으로 유효하지 않다”라는 뜻입니다. 결론을 말하면 JSX에서는 객체 자료형을 지원하지 않습니다. 객체 자료형에 속하는 함수나 배열도 JSX 표현식으로 사용하면 오류가 발생합니다.
만약 객체 자료형의 값을 페이지에 렌더링하고 싶다면, 프로퍼티 접근 표기법으로 값을 원시 자료형으로 바꿔 주어야 합니다.
코드를 불러오는 중 입니다 ...① 객체 objA의 a 프로퍼티 값 렌더링 ② 객체 objA의 b 프로퍼티 값 렌더링
객체 objA의 프로퍼티 a, b 의 값은 숫자이므로 objA.a와 objA.b는 산술 표현식 입니다. 따라서 JSX 문법으로 사용할 수 있습니다.

JSX 문법에서 지켜야 할 것들
JSX를 사용해 리액트 컴포넌트를 생성할 때 반드시 지켜야 할 문법들이 있습니다. 이 문법 가운데 몇 가지 중요한 내용만을 살펴보겠습니다.
닫힘 규칙
닫힘 규칙은 아주 간단한 규칙입니다. 즉, JSX의 모든 태그는 여는 태그가 있으면 반드시 닫는 태그도 있어야 한다는 규칙입니다. 이 규칙이 어떤 것인지 알아보기 위해 의도적으로 위반해 보겠습니다. 처음 보는 규칙을 익힐 때 좋은 방법의 하나는 그것을 위반해 보는 겁니다.
component 폴더에서 Body.js를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...① <h1>은 여는 태그는 있지만 닫는 태그가 없습니다. 따라서 JSX의 닫힘 규칙을 위반했기 때문에 오류가 발생합니다.
JSX 문법 오류가 발생하면 비주얼 스튜디오 코드에서는 붉은 밑줄로 오류가 있다고 표시합니다. 많이 사용하는 HTML 태그 중 <img>, <input>은 닫힘 태그 없이도 사용할 수 있는데, JSX에서는 이를 허용하지 않습니다. JSX에서 이 태그를 사용하려면 <img />, <input />과 같이 닫힘 태그를 반드시 병기해야 합니다.
최상위 태그 규칙
JSX가 반환하는 모든 태그는 반드시 최상위 태그로 감싸야 합니다. Body 컴포넌트를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...이 코드를 실행하면 Body 컴포넌트의 return 문 안에 최상위 태그가 존재하지 않아 오류가 발생합니다.
HTML 태그를 최상위 태그로 사용하지 않으려면, 다음과 같이 <React.Fragment> 태그를 사용하면 됩니다.
코드를 불러오는 중 입니다 ...① <React.Fragment> 태그는 리액트가 제공하는 기능이면서 컴포넌트입니다. 따라서 Body 컴포넌트에서 이 객체를 react 라이브러리에서 불러와야 합니다.
<React.Fragment>로 다른 태그를 감싸면 최상위 태그를 대체 하는 효과가 있습니다. 단 페이지에서 <React.Fragment> 태그는 렌더링되지 않습니다.
변경한 파일을 저장하고 개발자 도구의 [Element] 탭을 클릭합니다.

<React.Fragment>는 보이지 않고 두 개의 <div> 태그만 렌더링하는 것을 확인할 수 있습니다.
개발자 도구의 [Elements] 탭은 현재 페이지에 나타나는 요소들을 보여줍니다. [Elements] 탭을 살펴보면 페이지 요소가 어떤 요소의 자식인지, 어디에 위치했는지 등을 확인할 수 있습니다. 원하는 요소를 [Elements] 탭에서 쉽게 찾는 방법이 있습니다. 웹 페이지에서 마우스 포인터를 찾으려는 요소 위에 두고 오른쪽 마우스 버튼을 클릭한 다음, 단축 메뉴에서 [검사]를 클릭하면 자동으로 해당 요소를 [Elements] 탭에서 찾아 보여줍니다.
<React.Fragment> 대신 빈 태그 ‘<></>’를 사용할 수도 있습니다.
코드를 불러오는 중 입니다 ...<React.Fragment> 대신에 빈 태그 <></>를 작성했습니다. 그러면 빈 태그가 최상위 태그 역할을 수행합니다.
조건부 렌더링
리액트 컴포넌트가 조건식의 결과에 따라 각기 다른 값을 페이지에 렌더링하는 것을 조건부 렌더링이라고 했습니다. 그렇다면 조건부 렌더링은 주로 어떤 경우에 사용하는 걸까요? 페이스북 게시물의 ‘좋아요’ 버튼을 생각해 보겠습니다. 이 버튼은 사용자가 이미 ‘좋아요’를 눌렀다면 파란색, 그렇지 않으면 회색으로 표시합니다. 조건에 따라 페이지 요소의 모습이나 종류를 다르게 표시하고 싶을 때 조건부 렌더링을 사용합니다.
삼항 연산자를 활용한 조건부 렌더링
삼항 연산자를 활용하는 JSX 문법으로 조건부 렌더링을 구현할 수 있습니다. component 폴더의 Body.js를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...① 삼항 연산자를 이용해 변수 num의 값이 2로 나누어 떨어지면 짝수, 그렇지 않으면 홀수를 반환합니다.
저장하고 결과를 확인합니다.

if 조건문은 표현식에 해당하지 않기 때문에 JSX와 함께 사용할 수 없지만, 표현식인 삼항 연산자를 이용하면 조건에 따라 다른 값을 렌더링할 수 있습니다.
변수 num의 값을 바꾸면서 렌더링 결과가 어떻게 달라지는지 확인하길 바랍니다.
조건문을 이용한 조건부 렌더링
조건문은 자바스크립트의 표현식이 아니기 때문에 JSX와 함께 사용할 수 없지만, 다음과 같이 조건에 따라 컴포넌트가 반환하는 값을 다르게 표시하도록 만들 수 있습니다.
Body 컴포넌트를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...저장하고 페이지에서 결과를 확인합니다.

삼항 연산자를 이용하는 방법과 조건문을 이용하는 방법은 각기 장단점이 있
습니다. 삼항 연산자는 코드가 매우 간결하지만, 자주 사용할 경우 가독성을 해칠 우려가 있습니다. 그리고 삼항 연산자는 다중 조건을 작성하기 힘듭니다. 반면 조건문은 가독성은 좋으나 기본적으로 작성해야 할 코드가 많고 중복 코드가 발생할 우려도 있습니다. 따라서 여러분이 처한 상황에 맞게 적절히 선택해 사용하면 좋습니다.
JSX 스타일링
이번에는 JSX로 리액트 컴포넌트를 스타일링하는 방법을 살펴보겠습니다. 스타일링이란 CSS와 같은 스타일 규칙을 이용해 요소의 크기, 색상 등을 결정하는 일입니다.
인라인 스타일링
인라인 스타일링이란 JSX 문법으로 HTML의 style 속성을 이용해 직접 스타일을 정의하는 방법입니다. component 폴더의 Body.js를 다음과 같이 작성합니다.
코드를 불러오는 중 입니다 ...① JSX의 인라인 스타일링은 style={{스타일 규칙들}}과 같은 문법으로 작성합니다. 문자열로 작성 하는 HTML의 인라인 스타일링과는 달리, JSX의 인라인 스타일링은 객체를 생성한 다음 각각의 스타일을 프로퍼티 형식으로 작성합니다. 또한 리액트의 JSX는 background-color처럼 CSS에 서 속성을 표시할 때 사용하는 스네이크 케이스 표기법 대신 backgroundColor와 같이 카멜 표기법으로 작성해야 합니다.
스타일링을 잘 반영했는지 페이지에서 결과를 확인합니다.

인라인 스타일링은 하나의 파일 안에서 UI 표현을 위한 HTML과 스타일을 위한 CSS 규칙을 함께 작성할 수 있다는 장점이 있습니다. 그러나 페이지가 스타일을 계산할 때 불필요한 연산을 수행할 가능성이 있고, 스타일 규칙이 많으면 코드가 복잡해져 가독성이 떨어집니다.
스타일 파일 분리
HTML에서는 스타일을 정의한 CSS 파일을 따로 작성한 다음,
<link rel='stylesheet' href='css 파일 경로'>
형식으로 불러와 사용합니다. 리액트의 JSX도 마찬가지로 별도의 CSS 스타일 파일을 만들고 이를 불러와 스타일을 적용할 수 있습니다.Body 컴포넌트에 스타일 규칙을 적용할 파일 Body.css를 component 폴더에 만들고 다음과 같이 작성합니다.
코드를 불러오는 중 입니다 ...Body.js에서 className이 body인 요소의 배경색을 초록색으로, 글자 색은 파란색으로 지정하는 스타일 규칙을 Body.css에 작성했습니다.
다음에는 Body.css에 작성한 스타일 규칙을 컴포넌트에 적용하기 위해 Body.js를 다음과 같이 수정합니다.
코드를 불러오는 중 입니다 ...① CSS 파일은 import 문으로 경로만 명시하면 불러올 수 있습니다. ② JSX에서는 HTML 문법과는 달리 요소의 이름을 지정할 때 class 선택자가 아닌 className을 사 용합니다. class가 자바스크립트의 예약어 이기 때문입니다.
스타일이 잘 반영되었는지 페이지에서 결과를 확인합니다.

배경은 초록색, 글자 색은파란색인 문자열 body를 페이지에 렌더링합니다.