Tech Log

2.1 JSX 정의와 Fragment 본문

DSC PNU 4/리액트

2.1 JSX 정의와 Fragment

yuhee kim 2021. 4. 8. 11:56

JSX 문법은 간략하게 소개하고 다음 포스팅에 다른 문법을 게시한다.

 

JSX : 자바스크립트의 확장 문법이다.

JSX로 작성한 코드는 브라우저에서 실행되기 전에 코드가 번들링되는 과정에서 바벨을 사용하여 일반 자바스크립트의 형태의 코드로 변환된다.

 

*바벨 : 입력과 출력이 모두 자바스크립트 코드인 컴파일러를 말함. JSX 를 자바스크립트안에서 사용할 수 있게 해준다.

 

JXS는 리액트로 프로젝트를 개발할 때 사용되며 공식적인 자바스크립트 문법이 아니다. 바벨을 통해 개발자들이 임의로 만든 문법이다.

 

function App() {
  return (
    <div>
      Hello <b>react</b>
    </div>
  );
}
function App() {
return React.createElement(“div“, null, “Hello “, React.createElement(“b“, null, “react“));
}

 

위의 두 코드 중에서 가독성이 좋은 코드는 위쪽 코드라 생각된다.

또한, 아래 코드는 매번 React.createElement 함수를 사용하고 있어 번거롭다.

이와 같이 JSX는 HTML 코드와 비슷하게 생겨서 가독성이 높고 작성하기도 쉽다. 자바스크립트를 사용한다면 일일이 요소를 만들어야 하고 위와 같이 매번 함수를 호출해야할 것이다.

이러한 이유로 JSX를 사용한다.

 

JSX에서는 div나 span과 같은 HTML 태그를 사용할 수 있고, 컴포넌트도 사용가능하다.

 

 

2.1.1 JSX 문법

컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸야 한다.

 

import React from ‘react‘;


function App() {
  return (
    <h1>리액트</h1>
    <h2>작동하는지?</h2>
  )
}



export default App;

위와 같은 코드를 작동시킨다면 제대로 작동하지 않을 것이다. 

Failed to complie

웹 페이지나 터미널에 위와 같은 문구가 나올 것이다.

 

요소 여러 개가 하나의 부모 요소에 감싸져 있지 않아서 그렇다.

import React from 'react';
 
function App() {
  return (
    <div>
      <h1>리액트</h1>
      <h2>작동하는지?</h2>
    </div>
  );
}
 
export default App;

 위와 같이 <div> 요소로 감싸준다.

 

하나의 부모 요소로 여러 개의 요소를 감싸줘야 하는 이유는, 컴포넌트 내부가 하나의 DOM 트리 구조를 이루어야 하기 때문이다. 그래야 리액트가 하나의 컴포넌트만을 리턴하여, Virtual DOM에서 컴포넌트 변화를 감지해낼 때 효율적으로 비교할 수 있기 때문이다.

 

여기서 꼭 <div>가 아니더라도 리액트 v16부터 도입된 Fragment라는 기능을 사용할 수도 있다.

import React, { Fragment } from 'react';
 
function App() {
  return (
    <Fragment>
      <h1>리액트</h1>
      <h2>작동하는지?</h2>
    </Fragment>
  );
}
 
export default App;

Fragment는 상단에서 import로 react 모듈 안에 있는 Fragment라는 컴포넌트를 불러와야 사용할 수 있다.

 

import React from 'react';
 
function App() {
  return (
    <>
      <h1>리액트</h1>
      <h2>작동하는지?</h2>
    </>
  );
}
 
export default App;

혹은 Fragment로 위와 같이 간단하게 작성할 수도 있다. 그러나 빈 태그를 부모 태그로 이용하면 되지만 아직 많은 브라우저나 도구에서 지원되지 않기 때문에 사용 시 유의해야 한다.

 

 

여기서, Fragment에 대해서 자세히 설명하자면 아래와 같다.

 

이전에 설명했듯이, 리액트에서는 하나의 컴포넌트가 여러 개의 요소들을 반환하는 형태를 가져야 한다. 따라서 리액트를 사용하기 위한 문법인 JSX 를 쓸 때, return 문 안에는 반드시 하나의 최상위 태그를 적어 하나의 컴포넌트만을 리턴하게 한다.

 

이전에 의미없는 div요소를 썼는데, 이를 쓰지않고 Fragment를 사용해서 DOM에 별도의 노드를 추가하지 않고 여러 자식을 그룹화한다.

즉, div보다 Fragment를 쓰면 좋은 이유는 Fragment는 불필요한 DOM node의 생성을 막기때문에 메모리를 적게사용한다는 것이다. 

 

class Columns extends React.Component {
  render() {
    return (
      <div>
        <td>React</td>
        <td>div사용</td>
      </div>
    );
  }
}

class Table extends React.Component {
  render() {
    return (
      <table>
        <tr>
          <Columns />
        </tr>
      </table>
    );
  }
}

만약 위와 같이 div태그를 사용해서 코드를 작성했다고 하면 Table 컴포넌트를 사용할 때 복잡해질 수 있다.

 

<table>
  <tr>
    <div>
      <td>리액트</td>
      <td>div사용</td>
    </div>
  </tr>
</table>

render할 때 위와 같이 복잡하게 된다.

 

Fragment를 사용하면 불필요한 태그를 만들지 않아도 된다.

Fragment를 이용하면 DOM 구조에 반영이 되지 않으므로 부모 태그의 render를 생략할 수 있다. 

 

export default class FragmentComponent extends React.Component {
  render() {
    return (
      <React.Fragment>
        <h1>리액트 </h1>
        <h1>Fragment 사용</h1>
      </React.Fragment>
    );
  }
}

 

 

참조

 

'DSC PNU 4 > 리액트' 카테고리의 다른 글

async / await  (0) 2021.04.28
2.2 JSX와 자바스크립트  (2) 2021.04.08
props  (0) 2021.04.08
리액트의 필요성  (0) 2021.04.08
Component  (0) 2021.04.01
Comments