Logo

React API를 날 것으로 사용해보기

JSX 문법으로 코드를 작성하다보면 리액트(React)가 어디까지나 자바스크립트 라이브러리는 사실을 잊어버리기 쉬운 것 같습니다. 이번 포스팅에서는 리액트 API를 JSX 없이 날 것 그대로 자바스크립트로 사용하면서 리액트가 어떻게 작동하는지 알아보겠습니다.

JavaScript Library

리액트(React)를 비롯하여 최근에 많이 사용되는 프론트엔드(frontend) 라이브러리들은 기본적으로 자바스크립트로 HTML 엘리먼트를 동적으로 생성하여 DOM에 추가하는 방식을 취합니다. 따라서, 이러한 모던(modern)한 라이브러리로 작성된 SPA(Single Page Application)를 브라우저에서 실행 후 소스 보기를 해보면 HTML 코드는 달랑 <div> 엘리먼트 하나 밖에 없는 경우가 대부분입니다.

<body>
  <div id="root"></div>

  <script>
    // 자바스크립트 코드
  </script>
</body>

즉, 이 최상위 <div> 엘리먼트 안에 다른 여러 가지 엘리먼트를 채워주는 작업. 결국 이 작업을 위해 우리는 다양한 자바스크립트 라이브러리를 사용합니다.

Vanilla JavaScript

사실 HTML 엘리먼트를 동적으로 생성하여 DOM에 추가하는 것은 특별한 라이브러리를 없이도 자바스크립트 만으로 어렵지 않게 알 수 있는 일입니다.

예를 들어, <h1> 엘리먼트를 생성하여 기존 <div> 엘리먼트에 추가해주는 코드를 순수하게 자바스크립트 만으로 작성해보겠습니다.

<body>
  <div id="root"></div>

  <script type="module">
    const headingElement = document.createElement("h1");
    headingElement.textContent = "안녕, 리액트!";
    headingElement.className = "heading";

    const rootElement = document.getElementById("root");
    rootElement.append(headingElement);
  </script>
</body>

위 코드를 브라우저에서 실행하면 다음과 같은 HTML 페이지가 렌더링될 것입니다.

<body>
  <div id="root">
    <h1 class="heading">안녕, 리액트!</h1>
  </div>
</body>

React Raw API

동일한 작업을 리액트(React) API를 사용해서 구현하면 어떨까요?

우선 HTML의 <script> 태그로 React와 React DOM 패키지를 CDN 주소를 통해 불러오겠습니다. (실제 프로젝트였다면 npm과 같은 패키지 매니저를 사용했을 것이지만, 본 포스팅의 범위에서 벗어나는 부분이므로 최대한 간단하게 진행하겠습니다.)

<body>
  <div id="root"></div>

  <script src="https://unpkg.com/react@16.14.0/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16.14.0/umd/react-dom.development.js"></script>

  <script type="module">
    console.log(React.version);
    console.log(ReactDOM.version);
  </script>
</body>

이렇게 리액트 관련 패키지를 불러오면 ReactReactDOM을 브라우저 전역에서 사용할 수 있게 됩니다. 다음과 같이 버전이 콘솔에 출력된다면 정상적으로 패키지가 로딩이 된 것입니다.

16.14.0
16.14.0

리액트는 웹 브라우저 뿐만 아니라 네이티브와 같이 여러 플랫폼에서 돌아가도록 설계된 라이브러리 입니다. React 패키지는 플랫폼과 무방하게 UI 컴포넌트를 생성하기 위해서 사용되고, ReactDOM은 웹 플랫폼에서 UI 컴포넌트를 랜더링하기 위해서 사용됩니다.

이제 리액트 API를 사용해서 <h1> 엘리먼트를 생성하고, 기존 <div> 엘리먼트 안에 추가해보겠습니다.

<body>
  <div id="root"></div>

  <script src="https://unpkg.com/react@16.14.0/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16.14.0/umd/react-dom.development.js"></script>

  <script type="module">
    const headingElement = React.createElement(
      "h1",
      { className: "heading" },
      "안녕, 리액트!"
    );
    const rootElement = document.getElementById("root");
    ReactDOM.render(headingElement, rootElement);
  </script>
</body>

순수하게 자바스크립트로 작성한 코드와 상당히 유사하지만, 리액트 API를 사용햇을 때 달라지는 부분을 살펴보겠습니다.

  • React.createElement() 메서드를 이용해서, 리액트 엘리먼트를 생성하고 있습니다. 첫 번째 인자로 엘리먼트 이름을 넘기며, 두 번째 인자로 속성을 넘기고, 마지막 인자로 엘리먼트의 자식으로 들어갈 값을 넘김니다.

  • ReactDOM.render() 메서드를 이용해서, 브라우저 DOM 상의 <div> 엘리먼트에 리액트 엘리먼트를 추가합니다.

순수 자바스크립트 코드와 가장 중요한 차이는 HTML 엘리먼트가 아니라 리액트 엘리먼트를 생성했다는 점입니다. headingElement를 콘솔에 출력해보면 다음과 같이 리액트 엘리먼트에 대한 정보를 확인할 수 있습니다.

{
  "type": "h1",
  "props": {
    "className": "heading",
    "children": "안녕, 리액트!"
  },
  "key": null,
  "ref": null
}

JSX 코드는 Babel과 같은 트랜스파일러(transfiler)를 통해 브라우저가 실행할 수 있는 형태의 자바스크립트로 변환이 됩니다. 결국 브라우저는 JSX가 아닌 리액트 API로 작성된 코드를 실행하기 때문에, 이와 같이 리액트 API를 직접 사용해서 코딩을 해도 같은 효과를 낼 수 있는 것입니다.

마치면서

리액트(React)는 보통 JSX 코드로 작성하는 경우가 대부분이라서 React가 실제로 어떻게 동작하는지 잘 모르고 사용하는 경우가 많습니다. JSX를 사용해서 코딩을 하면 편하기 때문에 리액트 API를 날 것으로 직접 사용할 일은 매우 드물지만, 리액트 초창기에는 이렇게 JSX 없이 사용된 적도 있다고 합니다. 하지만 리액트도 결국은 자바스크립트라 라이브러리는 점을 염두해두시면 리액트를 이해하는데 도움이 되기에 한 번 다루어보았습니다.