본문 바로가기

Dev/[React.js]

[React] JSX(TSX) 를 사용하는 방법

반응형

 

INTRO


 

React로 화면을 개발할 때 사용되는 JSX 에 대해 정리한다.

 

 

 


 

1. JSX(TSX) 란?

- JSX는 Facebook에서 React 프레임워크를 개발하면서, React를 더 쉽게 사용할 수 있게 하기 위해 2013년에 개발되었다.

- React의 컨셉은 UI를 Javascript코드로 개발하는것.

- 기존 Javascript로 우리는 코드를 작성하는 방법을 알고있다.(DOM API를 사용)

// body 요소 가져오기
const body = document.querySelector('body');

// 새로운 div 요소 생성
const newDiv = document.createElement('div');

// div에 새로운 텍스트 노드 추가
const newContent = document.createTextNode('Hello, World!');
newDiv.appendChild(newContent);

// div 요소에 스타일 추가
newDiv.style.color = 'red';
newDiv.style.fontSize = '24px';

// body에 div 요소 추가
body.appendChild(newDiv);

// innerHTML 사용
const div = document.getElementById('newDiv');
div.innerHTML = '<p>Hello, World!</p>';

- 하지만 이러한 방식은 가독성이 좋지 않고, 복잡도도 빠르게 증가한다.

- 그래서 React는 아래와 같이 메서드를 사용하여 스크립트로 UI를 그린다.

"use strict";

function Test() {
  var style = {
    color: 'red',
    fontSize: '24px'
  };
  return React.createElement("div", {
    style: style
  }, "Hello, World!");
}

-그리고 이 방법을 좀 더 발전시킨 문법이 JSX이다.

- 아래의 코드를 보면 장점이 눈에 보일것이다.

function Test() {
  const style = { color: 'red', fontSize: '24px' };
  return (
    <div style={style}>Hello, World!</div>
  );
}

- 이렇게 작성된 JSX문법은 자바스크립트 표준이 아니므로, 컴파일 과정에서 바벨을 사용하여 createElement과 같은 React메서드를 사용하는 Javascipt 코드로 변환된다.

- 이 말은 즉, 굳이 JSX를 사용하지 않아도 createElement를 사용하면 React 개발이 가능하다는 말이다.

- 그럼에도 불구하고 JSX를 쓰는 이유는... 가독성이 좋고 편리하기 때문이다.

- 그리고 이 문법에 타입스크립트가 적용되면, TSX가 된다.

 

2. 문법

반드시 부모 요소 하나로 감싸는 형태로 작성해야한다.

- 감싸지 않으면 아래의 오류를 만나게된다.

Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag

- 감싸야 하는 이유는 React는 virtual DOM 을 사용하고, DOM은 트리 형태의 구조를 가지고 있다.

- 만약 최상위 요소가 여러개라면, 한개일 때 보다 변화를 감지하는데 많은 자원이 소모된다.

- 따라서 React에서는 최상위 요소를 한개로 제한하며, 상황에 따라 제한할만한 태그가 없을 경우 아래와 같이 사용하면 된다.

(Fragment는 React 16버전부터 지원한다)

import React, { Fragment } from 'react';

function MyComponent() {
  return (
    <Fragment>
      <h1>제목</h1>
      <p>내용</p>
    </Fragment>
  );
}

// 또는 
function MyComponent() {
  return (
    <>
      <h1>제목</h1>
      <p>내용</p>
    </>
  );
}

 

변수 바인딩 방법

- 아래와 같은 방법으로 JSX 내 자바스크립트 문법으로 변수를 선언하고, UI에 표현할 수 있다.

import React from 'react';
function CounterComponent() {
  const count = 0; // count state와 setCount 함수를 생성

  return (
    <div>
      <p>현재 숫자: {count}</p>
    </div>
  );
}

export default CounterComponent;

- 여기에 버튼을 추가하고, count의 값을 변경하여 화면에 다시 렌더링하려면 userState라는 hook을 사용해야 한다.

- React hook에 대해서는 별도로 정리 예정.

import React, { useState } from 'react';

function CounterComponent() {
  const [count, setCount] = useState(0); // count state와 setCount 함수를 생성

  const handleClick = () => {
    setCount(count + 1); // count 값을 1 증가시켜 업데이트
  };

  return (
    <div>
      <p>현재 숫자: {count}</p>
      <button onClick={handleClick}>+1</button>
    </div>
  );
}

export default CounterComponent;

 

조건부 렌더링 방법

- React의 조건부 렌더링은 아래와 같이 처리한다.

function LoginComponent() {
  const isLoggedIn = true;

  return (
    <div>
      {isLoggedIn
        ? <p>로그인되었습니다.</p>
        : <p>로그인이 필요합니다.</p>
      }
      
      {/* 또는 */}
      
      {isLoggedIn && <p>로그인되었습니다.</p>}
      {!isLoggedIn && <p>로그인이 필요합니다.</p>}
    </div>
  );
}

// 또는 
function LoadingComponent() {
  const status = 'success';

  switch (status) {
    case 'loading':
      return <div>Loading...</div>;
    case 'error':
      return <div>Error!</div>;
    case 'success':
      return <div>Success!</div>;
    default:
      return null;
  }
}

- 일반적인 케이스에서는 삼항 연산자나 && 연산자를 주로 사용하여 처리하며, Javascript의 if-else, switch문과 함께 사용하는 방법도 있다.

- Vue 와 비교하자면, 아예 화면에 그리지 않는 v-if의 동작과 유사하다.

- &&연산자가 있다면, || 연산자는 없을까?

- 아래와 같은 상황처럼 undefined가 렌더링되는 것을 방지하기 위해 || 연산자를 사용한다.

function MyComponent() {
  const name = undefined
  return (
    <div>
      {name || 'Unknown'}
    </div>
  );
}

 

HTML 태그에 class를 지정하는 방법

- 일반적으로 HTML 태그에 class를 지정하는 가장 큰 이유는 CSS 스타일을 적용하기 위함일것이다.

- 추가적으로 스크립트 레벨에서 해당 엘리먼트에 접근하기 위해서 활용하기도 한다.

- React에서는 클래스를 지정할 때 아래와 같이 class 대신 className을 사용한다.

  // 일반 HTML
  <p class="title">Hello, HTML!</p>
  
  // React
  <p className="title">Hello, React!</p>

- 그냥 class로 지정할 경우 React에서 아래와 같은 warning을 출력한다.

Warning: Invalid DOM property `class`. Did you mean `className`?

- 왜 꼭 className을 써야할까?

- 맨 위에서 JSX는 Javascript 표준 문법이 아니므로, 컴파일할 때 Javascript 로 변환된다고 언급했다.

- 이 부분에서, className은 아래와 같이 변환된다

// JSX
<div className="my-class">Hello, World!</div>

// Javascript
React.createElement("div", {className: "my-class"}, "Hello, World!");

- class 는 Javascript의 예약어이다.(class 이외에도 Javascript에는 몇 가지 예약어들이 있다.) 그러므로 className을 사용하는 것이다.

 

인라인 스타일을 작성하는 방법

- 실무에서는 별도의 폴더에 스타일을 정의해놓은 파일들을 모아놓고 관리하는것이 일반적이다.

- 그래서 엘리먼트 개별로 선언하는 인라인 스타일은 충돌을 방지하기 위해 가급적 지양하는것이 좋다.

- 인라인 스타일은 별도의 Javascript 객체로 선언하고, 이를 지정하는 방법이 있다.

- 일반적인 스타일 관련 문법의 경우, background-color와 같이 하이픈(-) 이 붙은 방식으로 네이밍을 한다.

- 그러나 인라인 스타일을 적용하기 위해 Javascript 객체로 선언할 경우, 카멜 케이스(backgroundColor) 와 같이 사용해주어야 한다.

(참고로 Vue의 스타일 바인딩에서도 무조건 카멜 케이스를 사용해야하는 규칙이 있다.)

function MyComponent() {
  const divStyle = {
    color: 'red',
    fontSize: '24px',
    backgroundColor: 'yellow',
  };

  return (
    <div style={divStyle}>
      This is a sample text.
    </div>
  );
}

- 이렇게 별도의 객체를 선언하는 방법 말고 직접 지정해줘도 된다.

function MyComponent() {
  return (
    <div style={{ backgroundColor: 'red', fontSize: '20px' }}>
      This is my component
    </div>
  );
}

 

 

 

 

-퍼가실 때는 출처를 꼭 같이 적어서 올려주세요!

 

반응형