이번 글에서는 React에서 사용되는 JSX 문법에 대해 알아보겠습니다. React 설치가 아직 되시지 않은 분들은 아래 글을 참고해서 React 설치를 먼저 진행해주시길 바랍니다.
React 프로젝트 생성 방법 (create-react-app)
React JSX
const element = <h1>Hello, world!</h1>;
이 재미있는 태그 구문은 문자열도 HTML도 아닙니다. 이는 JSX라고 하며 JavaScript의 구문 확장입니다. JSX 문법은 UI가 어떻게 보여야 하는지 설명하는 역할을 하게 되며 React와 함께 사용하게 됩니다. JSX는 템플릿 언어를 떠올리게 할 수 있지만 JavaScript의 모든 기능을 제공합니다.
JSX는 React “요소”를 생성합니다. 다음 섹션에서 DOM으로 렌더링하는 방법을 살펴보겠습니다. 아래에서 시작하는 데 필요한 JSX의 기본 사항을 찾을 수 있습니다.
왜 JSX인가?
React는 렌더링 로직이 본질적으로 다른 UI 로직, 즉 이벤트 처리 방식, 시간 경과에 따른 상태 변경 방식, 데이터 표시 준비 방식과 결합된다는 사실을 받아들입니다.
마크업과 로직을 별도의 파일에 넣어 인위적으로 기술을 분리하는 대신, React는 둘 다 포함하는 “구성 요소”라고 하는 느슨하게 결합된 단위로 관심사를 분리합니다. 다음 섹션에서 구성 요소에 대해 다시 살펴보겠지만 JS에 마크업을 넣는 것이 아직 익숙하지 않다면 이 강연을 통해 확신을 가질 수 있습니다.
React는 JSX를 사용할 필요가 없지만 대부분의 사람들은 JavaScript 코드 내에서 UI로 작업할 때 시각적 보조 도구로 유용하다고 생각합니다. 또한 React가 더 유용한 오류 및 경고 메시지를 표시할 수 있습니다.
JSX에 표현식 포함
아래 예제에서는 name이라는 변수를 선언한 다음 중괄호로 묶어 JSX 내에서 사용합니다.
const name = 'Josh Perez'; const element = <h1>Hello, {name}</h1>;
JSX의 중괄호 안에 유효한 JavaScript 표현식을 넣을 수 있습니다. 예를 들어 2 + 2, user.firstName 또는 formatName(user)은 모두 유효한 JavaScript 표현식입니다. 아래 예제에서는 JavaScript 함수 호출 결과인 formatName(user)을 <h1> 요소에 삽입합니다.
function formatName(user) { return user.firstName + ' ' + user.lastName; } const user = { firstName: 'Harper', lastName: 'Perez' }; const element = ( <h1> Hello, {formatName(user)}! </h1> );
가독성을 위해 JSX를 여러 줄로 나누었습니다. 필수는 아니지만 이 작업을 수행할 때 자동 세미콜론 삽입의 함정을 피하기 위해 괄호로 묶는 것이 좋습니다.
JSX = 표현식
컴파일 후 JSX 표현식은 일반 JavaScript 함수 호출이 되고 JavaScript 객체로 평가됩니다. 즉, if 문과 for 루프 내에서 JSX를 사용하고, 변수에 할당하고, 인수로 받아들이고, 함수에서 반환할 수 있습니다.
function getGreeting(user) { if (user) { return <h1>Hello, {formatName(user)}!</h1>; } return <h1>Hello, Stranger.</h1>; }
JSX로 속성 지정
따옴표를 사용하여 문자열 리터럴을 속성으로 지정할 수 있습니다.
const element = <a href="https://www.reactjs.org"> link </a>;
중괄호를 사용하여 속성에 JavaScript 표현식을 삽입할 수도 있습니다.
const element = <img src={user.avatarUrl}></img>;
속성에 JavaScript 표현식을 포함할 때 중괄호 주위에 따옴표를 넣지 마십시오. 따옴표(문자열 값의 경우) 또는 중괄호(표현식의 경우) 중 하나를 사용해야 하지만 동일한 특성에 둘 다 사용할 수는 없습니다.
JSX를 사용할 때 주의해야 할 점이 하나 있는데요. JSX는 HTML보다 JavaScript에 더 가깝기 때문에 React DOM은 HTML 속성 이름 대신 camelCase 속성 명명 규칙을 사용합니다. 예를 들어 class는 JSX에서 className이 되고 tabindex는 tabIndex가 됩니다.
JSX로 자식 지정
태그가 비어 있으면 XML과 같이 />로 즉시 닫을 수 있습니다.
const element = <img src={user.avatarUrl} />;
JSX 태그는 자식을 포함할 수 있습니다.
const element = ( <div> <h1>Hello!</h1> <h2>Good to see you here.</h2> </div> );
JSX 통한 주입 공격 방지 (Injection Attack)
JSX에 사용자 입력을 포함하는 것이 안전합니다.
const title = response.potentiallyMaliciousInput; // This is safe: const element = <h1>{title}</h1>;
기본적으로 React DOM은 렌더링하기 전에 JSX에 포함된 모든 값을 이스케이프 처리합니다. 따라서 애플리케이션에 명시적으로 작성되지 않은 것은 주입할 수 없습니다. 모든 것은 렌더링되기 전에 문자열로 변환됩니다. 이는 XSS(교차 사이트 스크립팅) 공격을 방지하는 데 도움이 됩니다.
JSX 통한 객체 표현
Babel은 JSX를 React.createElement() 호출로 컴파일합니다. 아래 두 예제는 동일하게 작동합니다.
const element = ( <h1 className="greeting"> Hello, world! </h1> );
const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' );
React.createElement()는 버그 없는 코드를 작성하는 데 도움이 되는 몇 가지 검사를 수행하지만 기본적으로 다음과 같은 객체를 생성합니다.
// Note: this structure is simplified const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world!' } };
이러한 객체를 “React 요소”라고 합니다. 화면에서 보고 싶은 것에 대한 설명으로 생각할 수 있습니다. React는 이러한 객체를 읽고 이를 사용하여 DOM을 구성하고 최신 상태로 유지합니다.