본문 바로가기
front/react

[react] Introducing JSX

by juniKang 2022. 8. 11.

다음을 변수선언으로 생각해라:

const element = <h1>Hello, world!</h1>

이 재미있는 태그 문법은 문자열도 아니고 HTML도 아니다.

 

이건 자바스크립트로 문법을 확장한 JSX라고 한다. 리엑트로 UI를 표현하기 위해 JSX를 사용하는 것을 추천한다. JSX는 템플릿 언어 같지만, 이건 모두 자바스크립트로 이루어져 있다.

 

JSX는 리엑트 "엘리먼트"를 생성한다. 다음 섹션에서 DOM에 이것들을 렌더링 시키는 것을 알아볼 것이다. 아래에서는, JSX를 시작하는데 필요한 기본적인 것들을 다룬다.

 

왜 JSX를 사용할까?

리엑트는 렌더링 로직이 내부저으로 UI 로직과 결합되어 있다는 사실을 인정한다. 어떻게 이벤트를 핸들링할지, 어떻게 상태를 변화시킬지, 어떻게 데이터를 보여주기위해 준비할지 등.

 

분리된 파일에 마크업과 로직을 둬서 인위적으로 기술을 분리하는 대신에, 리엑트는 둘 다를 담고 있는 "컴포넌트" 라고 부르는 낮은 결합력을 가진 유닛으로 개념을 분리한다.  나중에 컴포넌트를 다시 다룰 것이지만, 만약 JS에서 마크업을 두는것이 생소하다면, 이 게시물이 도움을 줄 것이다.

 

리엑트는 JSX 를 사용하지 않아도 된다. 하지만 대부분의 사람들은 자바스크립트 코드안에 UI를 넣는 것이 시각적으로 도움이 된다고 생각한다. 또한 리엑트가 유용한 에러와 경고 메시지를 표시할 수 있다.

 

이제 시작해보자!

 

JSX에 삽입하는 표현식

아래 예제에서, name이라고 부르는 변수를 선언하고, 중괄호로 감싸서 JSX안에서 사용했다.

const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

JSX의 중괄호 안에서는 모든 유효한 자바스크립트 표현식을 사용할 수 있다. 예를 들어 2 + 2, user.firstName, formatName(user) 는 모드 유효한 자바스크립트 표현식이다.

 

아래 예제에서, 자바스크립트 함수 호출의 결과를 삽입했다. 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표현식은 일반적인 자바스크립트 함수 호출이 된다. 그리고 자바스크립트 객체로 평가된다.

 

이는 JSX를 if문과 for 루프 안에 두거나, 변수에 할당하거나, 아규먼트로 받거나, 함수의 리턴값으로 주는것을 가능하게 한다.

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranget.</h1>;
}

 

JSX로 애트리뷰트 특정하기

쌍따음표를 사용해서 애트리뷰트로 문자열을 특정할 수 있다:

const element = <a href="https://www.reactjs.org"> link </a>;

애트리뷰트에 자바스크립트 표현식을 넣기 위해 중괄호를 사용할 수 있다:

const element = <img src={user.avatarUrl}></img>;

애트리뷰트로 자바스크립트 표현식을 삽입할 때 중괄호를 쌍따음표로 감싸지 마라. 문자열에 쌍따음표, 표현식에 중괄호를 사용할 수 있지만, 하나의 애트리뷰트에 둘 다 사용할 수는 없다.

주의:
JSX는 HTML보다는 자바스크립트에 가깝기 때문에, 리엑트 돔은 HTML 애트리뷰트 네이밍 대신에 낙타표기법으로 프로퍼티 네이밍 컨벤션을 사용한다.

예를 들어, 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는 주입 공격을 막는다

JSX에서 유저 인풋 값은 안전하다:

const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;

기본적으로, 리엑트 돔은 렌더링 하기 전에 JSX에 삽입된 모든 값을 탈출한다. 그러므로 애플리케이션에 명시적으로 어떤 값도 절대 넣을 수 없다. 모든 것은 렌더링 되기전에 문자열로 변환된다. 이것은 XSS(cross-site-scripting) 어택을 막는데도 도움을 준다.

 

JSX 로 객체 표현

바벨은 JSX를 React.createELement()를 호출해서 컴파일 한다.

 

이 두가지 예제는 동일하다:

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

React.createElement()는 버그로부터 자유로운 코드를 사용하는데 도움을 주는 몇가지 체크를 수행하기도 하지만, 본질적으로는 다음과같은 객체를 만들어준다 : 

// Note: 이 객체는 간소화되었다
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

이 객체는 "리엑트 엘리먼트"라고 부른다. 화면에 보여줄 설명서라고 생각하면 된다. 리엑트는 이 객체들을 일고, 돔을 생성하고 유지하는데 사용한다.

 

다음 섹션에서 돔에 리엑트 엘리먼트를 렌더링하는 과정을 살펴볼 것이다.

Tip:
에디터에서 "Babel" language definition 을 사용하는 것을 추천한다. ES6와 JSX 코드를 적절히 하이라이트 해준다.

 

'front > react' 카테고리의 다른 글

[react] Components and Props  (0) 2022.08.12
[react]Rendering Element  (0) 2022.08.12
[react] Hello World  (0) 2022.08.08

댓글