2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

新バージョンの React は何が違うかを理解する前にそもそも JSX とは何か解説する

Last updated at Posted at 2025-03-10

React 19 がリリース

React 19 がリリースされ、新たな機能や最適化が加わりました。

新バージョンの機能の前に、この記事ではベースとなっている技術について取り扱っていきます!React を学ぶ方に向けてかなり噛み砕いて説明します!

JSX ( JavaScript XML )とは?

JSX は JavaScript 内で HTML のような構文を記述できる React の拡張構文です。通常の JavaScript では UI を表現するために document.createElement()React.createElement() を使用する必要があります。

通常の JavaScript:

// document.createElement() を使った場合:

document.addEventListener("DOMContentLoaded", () => {
    // HTML要素を作成
    const container = document.createElement("div");
    container.innerHTML = `
        <h1>JavaScriptでHTMLを動的に追加</h1>
        <p>このHTMLはJavaScriptで生成されました。</p>
        <button id="clickMe">クリックしてメッセージを表示</button>
        <div id="message"></div>
    `;

    // 作成したHTMLをbodyに追加
    document.body.appendChild(container);

    // ボタンのイベントリスナーを追加
    document.getElementById("clickMe").addEventListener("click", () => {
        document.getElementById("message").innerText = "ボタンがクリックされました!";
    });
});

または、

// React.createElement() を使った場合:

import React, { useState } from "react";

export default function App() {
    const [message, setMessage] = useState("");

    return React.createElement(
        "div",
        null,
        React.createElement("h1", null, "JavaScriptでHTMLを動的に追加(React)"),
        React.createElement("p", null, "このHTMLはReact.createElement()で記述されています。"),
        React.createElement(
            "button",
            { onClick: () => setMessage("ボタンがクリックされました!") },
            "クリックしてメッセージを表示"
        ),
        React.createElement("div", null, message)
    );
}

のようになります。

JSX の構文:

import { useState } from "react";

export default function App() {
    const [message, setMessage] = useState("");

    return (
        <div>
            <h1>JavaScriptでHTMLを動的に追加(React)</h1>
            <p>このHTMLはReactのJSXで記述されています。</p>
            <button onClick={() => setMessage("ボタンがクリックされました!")}>
                クリックしてメッセージを表示
            </button>
            <div>{message}</div>
        </div>
    );
}

JSX によってかなり見やすくなりました。

このような拡張構文は、ブラウザが直接理解するのではなく、JavaScript に変換されて実行されます。詳しくは参考に書いています。

そもそもなぜ React では JSX を使うのか?

React は Facebook (現 Meta) によって開発されたオープンソースの JavaScript ライブラリです。同社のアプリ の UI が複雑になり、メンテナンスが難しくなっていたときに社内で開発されました。

その時の目標は2つです。

  • コンポーネントベース の開発手法を導入し、コードを再利用しやすくする
  • 仮想DOM ( Virtual DOM ) を活用し、UIの更新を効率化する

コンポーネントベースは UI を小さな部品に分割して開発することです。こうすることによって再利用しやすく、変更、管理も楽になります。

例です。

Button.jsx
import React, { Component } from "react";

class Button extends Component {
  render() {
    return <button>{this.props.text}</button>;
  }
}

export default Button;

App.jsx
import Button from "./Button";

function App() {
  return (
    <div>
      <h1>コンポーネントの例</h1>
      <Button text="クリック" />
      <Button text="送信" />
    </div>
  );
}

export default App;

これをReact.createElement()で書くと記述が冗長で、可読性が低かった、という訳です。

import React from "react";

function Button({ text }) {
  return React.createElement("button", null, text);
}

function App() {
  return React.createElement(
    "div",
    null,
    React.createElement(Button, { text: "クリック" }),
    React.createElement(Button, { text: "送信" })
  );
}

export default App;

React がオープンソースプロジェクトとなり、その後普及されるときには JSX は React の標準的な書き方となりました。
JSX は可読性が高く、HTML ライクに書くことができ、コンポーネントの記述が簡単です。また{ }を使った JavaScript 式の統合もできるので動的にコンテンツを生成できます。

新バージョンで変わったこと

JSX がより扱いやすくなった例を紹介します。

async function 内で JSX を直接返せるようになった

例えば、以下のように短く書くことができます。

React 19:

async function App() {
  const response = await fetch("https://api.example.com/data");
  const data = await response.json();

  return <div>{JSON.stringify(data)}</div>;
}

export default App;

なお、これはサーバーコンポーネントのみで、クライアントコンポーネントでは従来通りです。useEffect内で await を使い、useStateを更新します。

"use client";
import { useState, useEffect } from "react";

function App() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    async function fetchData() {
      const response = await fetch("https://api.example.com/data");
      const result = await response.json();
      setData(result);
    }
    fetchData();
  }, []);

  return <div>{data ? JSON.stringify(data) : "Loading..."}</div>;
}

もう少し具体的に説明します。

同期的な設計とは以下のような流れです。

function App() {
  return <h1>Hello, world!</h1>; 
}
  1. App コンポーネントが呼び出される
  2. return 文で JSX を返す
  3. React がその JSX を仮想DOMに変換
  4. 実際の DOM に反映

このとき、すべての処理は即座に完了しなければならないため、途中で非同期の処理を待つことはできません。
よってコンポーネント関数は async にできず、また、awaitを使うとエラーとなっていました。

設計の意図に立ち返ると、一度の レンダリング で UI を確定させ、不要な再計算を防ぐ ことが重要であったとも言えます。

設計思想については、宣言的 UI について参考にリンクを載せました。
React は 「現在の状態に応じた UI を宣言的に定義する」 ことを重視します。React より前からあった jQuery のように主導で DOM を更新するのではなく、データに応じた UI を返します。

まとめ

JSX は React の中核をなす構文です。これを理解してから新バージョンの更新情報を確認すると理解が深まると思います!

参考

Babelトランスパイラ

JSX は、一度 JavaScript に変換されて実行されます。React の Babel トランスパイラ を使うことで、JSX は React.createElement() の形に変換されます。

例えば、Babel によってこのように変換されます

// 変換前
const eleme
nt = <h1>Hello, world!</h1>;
// 変換後

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

Promise

宣言的UI

2
3
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?