React 기본적인 구조

React는 구성 요소라는 것을 정의하고 화면의 표시까지 구축해 본다. 그 기본적인 구조에 대해 설명한다.

React을 구성하는 3개 파일

React 응용 프로그램에는 기본적으로 일부 파일이 생성되어 있다.

React를 구성하는 3 개의 파일

그 중에는 응용 프로그램 본체를 구성하는 파일은 3가지가 있다. 그 역할을 설명한다.

  • index.js

    • src 폴더에 포함되어 있다. 메인 프로그램이라고 할 수 있다. 여기에서 HTML 템플릿 및 JavaScript의 컴포넌트를 조합하여 렌더링하고 실제 표시한다.
  • App.js

    • src 폴더에 있다. 이것은 컴포넌트를 정의하는 프로그램이다. 실제로 화면에 표시되는 내용 등은 여기에서 정의된다.
  • index.html

    • public 폴더에 있다. 메인 프로그램인 index.js에 대응되는 것으로, HTML 템플릿 파일이다. 이 파일이 직접 표시되는 것은 아니고, index.js에 의해 일어 와서 렌더링된 결과가 표시된다.

빌드 및 구성이 바뀐다!

주의할 점은 이것들은 Node.js 응용 프로그램으로 동작하는 경우의 구성이라는 점이다. 서버에 Node.js가 있어서 그대로 기동하는 것이라면 이대로도 괜찮지만, 보통의 Web 서버에 올려서 사용하는 경우 액세스하면 index.js가 읽어와서 렌더링되는 방법은 좀 무리일 것이다.

이런 경우는 앞전에 설명한 바와 같이 npm run build 응용 프로그램을 빌드한다. 이렇게 하면 폴더의 구성이 달라진다. 폴더의 루트에 index.html이 새로 생성하고, 그 안에 index.js에 해당하는 스크립트가 실행된 표시를 만들 수 있게 된다.

실제로 해보면 알겠지만, index.html는 몰라도 거기에서 호출되는 스크립트는 빌드 시에 새롭게 생성되고, 코드 자체가 전혀 다르게 되어 있다. 자동 생성되어서 인지 줄바꿈도 되지 않아서, 사람이 읽기에는 어렵다. 즉, 빌드하여 생성된 것은 더 이상 “사람이 편집 할 것"으로 생각하지 않는다는 것이다. 일반 프로그래밍 언어는 소스 코드를 컴파일하면 바이트 코드를 생성하지만, 그것에 가까운 것으로 생각하면 될 것이다.

따라서, 우리가 프로그래밍하는 것은 어디까지나(빌드하기 전) index.jsApp.js이다. 수정하는 경우에도 이를 편집하고 다시 빌드하여 생성된 것을 배포할 수 있다. 지금까지의 “HTML 및 JavaScript는 작성한 것이 그대로 서버에 업로드 되어, 브라우저에 로드되어 동작한다"라는 상식은 버려야 한다.

React에는 “개발시 쓰는 코드"와 “실제로 배포되는 코드"는 전혀 다르다. React는 컴파일러 언어로 개발하는 것과 같은 느낌으로 만들 필요가 있다.

(※ 단, Node.js 그 자체가 서버에 있고, Node.js 응용 프로그램으로 실행한다면, 이야기는 별도이다. 이 경우는 이른바 인터프리터가 서버에 있고 컴파일하지 않아도 동작하는 것처럼 상황이라고 생각해도 좋다)

index.js 어플리케이션의 프로그램

생성된 소스 코드를 살펴 보겠다.

응용 프로그램의 프로그램에 대해

메인 프로그램인 index.js를 설명한다. 아래에 소스 코드를 올려 둔다. 내용을 순서대로 설명하겠다.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

import 문에 대해

최초에 import 문이 여러개가 작성되어 있는데, 이는 외부의 모듈을 로드하는 것이다. 이 import 문은 JavaScript에서는 그다지 익숙하지 않을지도 모르지만, 이것은 ES6(ECMAScript 6 Edition)에서 지원되는 기능이다. React에는 “Babel"라는 ES6 대응의 트랜스 컴파일러를 사용하고 있기에 이러한 ES6의 기능을 사용할 수 있다.

최초에 “react”, “rect-dom"라는 모듈을 로드하고 있고, 이것들이 React의 본체이다. 또한 다음의 “./App”, “./index.css"은 여기에서 사용하는 컴포넌트와 스타일 시트이다. 이 또한 import로 로드한다.

ReactDOM.render

그 다음에 ReactDOM 객체의 “render"라는 메소드를 실행하고 있다. 이것은 이 프로그램에서 실행하는 유일한 처리이다. 이 컴포넌트를 지정된 위치에 넣어 렌더링을 수행하는 것으로, 다음과 같이 실행한다.

ReactDOM.reder(컴포넌트, 조합 대상 요소);

첫번째 인수는 App.js으로 정의하고 있는 App 컴포넌트를 지정하고 있다. 그리고 두번째 인수는 root라는 ID의 요소를 지정한다. 그러면 App 컴포넌트가 root 태그에 포함된 코드가 렌더링되고 출력된다.

JSX 대해

여기에서는 render 인수에 <App />라는 것이 지정되어 있다. 이 App 컴포넌트의 태그이지만, JavaScript의 인수에 직접 HTML 태그를 작성되어 있어서 이상하게 생각되었을 것이다. 이것은 JSX 라는 기능을 이용한 것이다. 이것은 아마도 “JavaScript Expression"을 약자일 것이다. 이 JSX는 HTML 태그를 그대로 JavaScript 코드 내에 작성할 수 있는 기능이다. 단독 태그가 아니라, 태그 안에 별도의 태그가 포함된 복잡한 것도 처리할 수 있다.

<App />이라는 값을 작성하는 것으로, <App />라는 태그에 정의된 사용자 지정 컴포넌트를 render 에 지정하고 있다.

index.html 탬플릿

이어서 Web 페이지의 템플릿인 index.html을 살펴 보자. 아래에 소스 코드를 올려 둔다. 긴 코멘트가 있지만 이것은 생략하였다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <!--
      ... 중략 ...
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <!--
      ... 중략 ...
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      ... 중략 ...
    -->
  </body>
</html>

이 코드는 그렇게 어렵지는 않다. 몇 가지 설명을 하겠다

%PUBLIC_URL% 문에 대해

헤더 부분을 보면 <link> 태그에 href="%PUBLIC_URL%/favicon.ico와 같이 값이 설정되어 있다. 이 %PUBLIC_URL%는 React에 제공하는 접두어로 공개 사이트 URL이 설정된다.

id="root" 태그에 대해

<body> 부분에 <div id="root"></div>라는 태그가 있다. 이 id="root"라는 것이 어디선가 본 기억이 있을 것이다. 그렇다, index.js의 ReactDOM.render 인수로 document.getElementById('root')로 지정하였던 것이다. 지정한 root가 <div id="root"></div>라는 이 태그를 가르킨다. 즉,이 태그 부분에 <App /> 컴포넌트를 포함하도록 되어 있다.

이 index.html 템플릿의 기능은 이뿐이다. 단지 <div id="root"></div> 태그를 제공하고 여기에 컴포넌트가 포함되는 템플릿이다.

App.js App 컴포넌트

응용 프로그램의 표시 부분은 “컴포넌트(component)“에 의해 이루어진다. 이 소스 코드가 어떻게 되어 있는지 살펴 보자.

기본적으로 App.js라는 스크립트 파일이 준비되어 있으며, 여기에 App이라는 컴포넌트의 코드가 기술되어 있다. 그 내용을 아래에 올려 둔다.

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

export default App;

코드의 내용을 정리해 보겠다.

· import 문에 대해

먼저 import 문에서 여러 모듈을 가져올 수 있다. 첫줄에 import React {Component} from 'react';라는 문장이 있는데, 이것이 React의 컴포넌트 관계의 개체를 로드하는 부분이다. 이 후에 아래 두줄은 logo.svg과 App.css를 로드하기 위한 문장이다.

· App 클래스에 대해

여기에서는 App 클래스라는 것이 정의되어 있다. JavaScript에서도 클래스를 만들 수 있다. ES6라는 에디션에서 클래스 정의가 가능하게 되어 있다. (React이 ES6임을 기억하자). 여기에서는 App 클래스를 다음과 같이 정의하고 있다.

class App extends Component {...}

Component 클래스를 상속하여 App 클래스를 생성하고 있다는 것을 알 수 있다. 이 Component라는 것이 컴포넌트의 기반이 되는 클래스이다. 이를 상속하여 컴포넌트로 작동하도록 한다.

· render 메소드에 대해

이 App 클래스에는 render라는 메소드가 하나 포함되어 있다. 이것은 다음과 같이 작성된다.

render () {
    return ...;
}

return으로 반환되는 값이 그대로 렌더링의 내용으로 처리된다. 여기에서는 return하는 값은 다음과 같은 형태로 되어 있다.

return (<div className = "App"> ... 생략 ... </div);

HTML 태그가 작성되어 있다. 이것이 “JSX ‘라는 것이다. 여기에서 반환되는 태그가 그대로 App 컴포넌트의 표시 내용으로 출력된다.

 

이것으로 React 응용 프로그램의 기본적인 내용을 알게 되었다. “컴포넌트를 정의하고 그것을 통합하여 렌더링 한다"는 것이 React에서 실행하고 있는 전부이다.



최종 수정 : 2021-08-29