INDEX
開く ▼

React学習:仕組み編|JSXがReact要素に変換されてレンダリングされるまで(最小限の構成で仕組み理解)

Learning React How Work Kiu5v4sstk

JSXがどのように変換されて最終的に画面上に表示されるか、最小限の構成をその仕組みを学習してみたので、書き残しておきます。

「この記述はなんとなくこうなっているのだろう...」という曖昧な理解のまま放置しておかないように「なんとなく理解禁止」というシリーズでJavaScriptやReactの学習記録を残していて、誰か1人にでも参考になれば嬉しいです...!

JSXとは

JSX(JavaScript XML)とは、HTMLのような書き方でJavaScriptソースを記述できるようにした Meta(旧Facebook)が開発した構文です。

例えば、下記のようにシンプルな見出し要素を記述できます。

const component = <h1>Hello</h1>;

ちなみにこのHTMLタグ等はHTMLではなく、全てJavaScriptのソースです。なので、下記のようにJavaScriptのコードを実行するための印(中括弧{})の中であれば、計算結果を書くこともできます。

const myname = 'Tsukasa';
const component = <h1>Hello {myname}!</h1>;
// componentが出力するHTML結果:<h1>Hello Tsukasa!</h1>

JSXがReact要素に変換されてレンダリングされるまでの流れ

下記の記述でH1タグでHello Worldを画面上に表示できます。

<div id="app"></div>
const root = createRoot(document.getElementById('app'));
root.render(<h1>Hello, world!</h1>);

上記の記述を2つに因数分解すると、ざっと下記の流れになります。

① babel等を使ってJSXをReact要素に変換

const component = <h1>Hello, world!</h1>;

上記のようなJSXで書いた構文は、babel等のコンパイラを使って下記のようなReact.createElement()メソッドを使ったJavaScript形式のソースに変換されます。

const component = React.createElement("h1", null, "Hello, world!");

前者と後者の実行結果は同じで、JSXはReact.createElement()の記述のシンタックスシュガーということになります。

シンタックスシュガー(英:syntax sugar)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

② createRoot().renderメソッドでReact要素をHTMLとして挿入

あとは簡単で、React要素に変換したオブジェクトを材料に、createRoot().renderメソッドを使ってHTMLとして挿入します。

<div id="app"></div>
// HTMLを挿入するルートを特定
const root = createRoot(document.getElementById('app'));
// renderメソッドを使ってReact要素をルートに挿入
root.render(React.createElement("h1", null, "Hello, world!"));

初めは下記のようにrenderメソッドの引数に直接JSX構文を書いていましたが、上記のコードでも下記でも実行結果は同じです。

const root = createRoot(document.getElementById('app'));
root.render(<h1>Hello, world!</h1>);

内部的に、<h1>Hello, world!</h1>というJSX構文をReact.createElement()に変換していた訳です。

補足

ちなみに、React.createElement()の戻り値をコンソールで確認すると、下記のようなオブジェクトを確認できます。

▼object
$$typeof: Symbol(react.element)
key: null
props: {children: 'Hello, world!'}
ref: null
type: "h1"
_owner: null

React.createElement()の3つの引数がそれぞれ代入されていて...

といった形で割り当てられて、このオブジェクトを使ってHTMLタグを作って挿入しているイメージになります。

余談ですが、こうして一つひとつ理解していくとJSXは結局ただのJavaScriptのオブジェクトだという事が分かります。JSX構文とReact.createElement()は書き方が違うだけで機能的には同じで、React.createElement()が返すのは普通のJavaScriptなので、JSXは色々変換された結果、最終的にはJavaScriptのオブジェクトとなります。

実際にJSXがレンダリングされるまでの流れを最小限の構成で試してみる

下記が今回の最小限の構成です。

dist/
├── assets/
└── index.html
src/
├── index.html
└── main.js
babel.config.json
package.json
vite.config.js

扱っている環境やツールは下記の通り。

学習のためにこのような環境にしましたが、普通はNext.jsやRemix等のReactセットアップコマンドやViteのReactテンプレートのセットアップコマンドを叩けば簡単にReactを試せます。

1/2|Viteでバンドルするための環境を整える

Viteセットアップ時にReactのセットアップテンプレートは使わず、Vanillaを選択してフラットな環境にします。

yarn create vite
# Select a framework:
# Vanillaを選択
# Select a variant:
# JavaScriptを選択
cd vite-project

説明に不要なファイルは省きますが、セットアップ後は下記のような構成になります。

vite-project/
├── counter.js
├── index.html
├── main.js
└── package.json

これでyarn buildを叩けば、index.htmlをエントリーポイントにしてmain.jsのバンドルもした上でプロジェクトルートにdistが吐き出されます。

2/2|JSX構文をReact要素に変換するためのbabel環境を整える

babelの最小限のセットアップ方法は公式ガイドを参照すれば理解できます。

What is Babel?|BABEL

# 必要なパッケージをインストール
yarn add --dev @babel/core @babel/cli @babel/preset-react

インストール後、babelの設定ファイルをプロジェクトルートに設置。

// 
{
  "presets": [
    "@babel/preset-react"
  ]
}

package.jsonのscripts.buildにviteも含めたコマンドを設定します。

{
  "scripts": {
    "dev": "vite",
    "build": "./node_modules/.bin/babel ./src/main.js --out-file ./src/main.babel.js && vite build",
    "preview": "vite preview"
  },
  "devDependencies": {
    "@babel/cli": "^7.24.8",
    "@babel/core": "^7.25.2",
    "@babel/preset-env": "^7.25.3",
    "@babel/preset-react": "^7.24.7",
    "vite": "^5.4.0"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  }
}

./node_modules/.bin/babel ./src/main.js --out-file ./src/main.babel.jsの記述が、babelを使って./src/main.js./src/main.babel.jsに吐き出すコマンドになります。

babel実行前の./src/main.jsと実行後の./src/main.babel.jsは下記の通り。

import './style.css'
import ReactDOM from 'react-dom';
import React from 'react';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('app'));
root.render(<h1>Hello</h1>);
import './style.css';
import ReactDOM from 'react-dom';
import React from 'react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('app'));
root.render( /*#__PURE__*/React.createElement("h1", null, "Hello"));

root.render()の引数が<h1>Hello</h1>のJSX構文からReact.createElement("h1", null, "Hello")のReact要素に変換されていることが分かります。

あとは、後続のvite buildコマンドによって、src/index.htmlで挿入している<script src="./main.babel.js" type="module"></script>を読んで、main.babel.jsのインポートされているパッケージを全てバンドルしてくれます。

ビルド前の`index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="./main.babel.js" type="module"></script>
  </body>
</html>

ビルド後の`index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
    <script type="module" crossorigin src="./assets/index-CTqbuTW-.js"></script>
    <link rel="stylesheet" crossorigin href="./assets/index-BfibREyH.css">
  </head>
  <body>
    <div id="app"><!-- ./assets/index-CTqbuTW-.jsによって<h1>Hello</h1>が挿入される --></div>
  </body>
</html>

References

スキルアップ転職を目指すなら「エンジニア特化型転職エージェント」を活用しよう

もし下記のような悩みがあれば、スキルアップを目的とした転職をするのもひとつの手段です。

・モダンな環境での経験が積みたい...
・実際に働いてみてもっと取り組みたい案件が明確になった
・学習をしているが先が見えずこのまま1人でスキルアップするのは辛い...
・今の職場ではなかなか理想の案件にアサインしてもらえない...

レバテックキャリアやユニゾンキャリアといったエンジニアに特化した転職エージェントであれば、初回面談でまずは現状の悩みを聞いてくれたり丁寧にヒアリングをしてくれます。

さらに、プロのキャリアアドバイザーが企業個別の技術質問・頻出質問の対策、模擬面接でのサポート、ES対策、企業分析・自己分析、求人の紹介など、あなたの転職を徹底サポートしてくれて...下記のどの状況の人でもメリットがあるので、まだ使っていない人は無料相談から進めておきましょう。

シチュエーション メリット
既に採用面接を控えている人 模擬面接や面接企業の分析をしてくれる
応募先企業の固有の
質問を気にしている人
応募先企業の頻出質問や気にしていることなど、企業ごとの対策をしてくれる
応募企業がまだ少ない人 応募したい企業をヒアリングしてくれ、ベストな求人をピックアップしてくれる
転職に自信がない人 転職理由や希望条件をヒアリングの上、ベストな応募企業や採用面接のコツをレクチャーしてくれる

IT・Web業界のエンジニア転職に強いエージェントがおすすめ。筆者や同僚も実際に活用していたエージェントをまとめておきます。

現役がおすすめするIT・Webエンジニア特化型の転職エージェント

IT・WEB・ソーシャルゲーム業界への転職ならGEEKLY
The Service Aid Your Career.
ボタンをクリックして無料の転職相談から始めよう!
IT・Web業界での転職なら【レバテックキャリア】
The Service Aid Your Career.
ボタンをクリックして無料の転職相談から始めよう!
IT・Web・ゲーム業界特化の転職エージェント【ユニゾンキャリア】
The Service Aid Your Career.
ボタンをクリックして無料の転職相談から始めよう!
ITエンジニア就職に特化した【ウズカレIT】
The Service Aid Your Career.
未経験ITエンジニアの就職サポートに特化したサービスに無料相談しよう!