JSX

JavaScript 内に HTML ライクな構文を記述し、UI コンポーネントを宣言的に定義する React の拡張構文

Reactフロントエンド
JSX」の技術書を見る →

JSX とは

JSX は、HTML に似た記法で UI を宣言的に書けるようにする JavaScript の構文拡張である。ブラウザはこの記法をそのまま解釈できないため、Babel や TypeScript などのトランスパイラが関数呼び出しへ変換してから実行する。変換先は React 17 以降の新しい方式では react/jsx-runtime の関数、それ以前は React.createElement() である。2013 年に React とともに Facebook が公開した。React と組み合わせて使われることが圧倒的に多いが、JSX は構文拡張、React はライブラリという別物で、公式ドキュメントも両者を独立して使えると明記している。

JSX のトランスパイル

JSX のトランスパイルのコード例を示す。

// JSX (開発者が書くコード)
const element = <Button onClick={handleClick} variant="primary">Click me</Button>;

// トランスパイル後 (React 17+ の新しい JSX Transform)
import { jsx as _jsx } from "react/jsx-runtime";
const element = _jsx(Button, { onClick: handleClick, variant: "primary", children: "Click me" });

JSX はシンタックスシュガーであり、最終的には関数呼び出しに変換される。React 17 で導入された新しい変換方式 (React 16.14 / 15.7 / 0.14.10 にもバックポートされている) では、変換後のコードがランタイム側の関数を自前で import するため、JSX を書くだけのファイルで React を import する必要がなくなった。古い React.createElement() へ変換する方式も動き続けており、公式には削除予定なしとされている。

JSX の基本ルール

JSX の基本ルールのコード例を示す。

// 1. 式の埋め込み: {} 内に JavaScript 式を記述
<h1>{user.name}</h1>
<p>{isLoggedIn ? 'Welcome' : 'Please login'}</p>

// 2. className (class ではない)
<div className="container">...</div>

// 3. 単一のルート要素 (Fragment で囲む)
<>
  <h1>Title</h1>
  <p>Content</p>
</>

// 4. 自己閉じタグ
<img src="photo.jpg" alt="Photo" />
<Input type="text" />

// 5. 配列のレンダリング (key が必須)
{items.map(item => <li key={item.id}>{item.name}</li>)}

TSX (TypeScript + JSX)

TypeScript で JSX を使う場合、ファイル拡張子は .tsx にする。props の型チェックが効く。

interface ButtonProps {
  variant: 'primary' | 'secondary';
  onClick: () => void;
  children: React.ReactNode;
}

function Button({ variant, onClick, children }: ButtonProps) {
  return (
    <button className={`btn btn-${variant}`} onClick={onClick}>
      {children}
    </button>
  );
}

// ✅ 型チェックが効く
<Button variant="primary" onClick={handleClick}>Click</Button>
// ❌ コンパイルエラー: variant に "danger" は許可されていない
<Button variant="danger" onClick={handleClick}>Click</Button>

JSX と XSS

React は JSX の {} に埋め込んだ値を文字列として扱い、タグとして解釈させない。要素の中身に値を差し込む限り、この自動エスケープが XSS を防いでくれる。

const userInput = '<script>alert("XSS")</script>';
<p>{userInput}</p>
// 出力: <p>&lt;script&gt;alert("XSS")&lt;/script&gt;</p>
// スクリプトは実行されない

ただし「React を使えば XSS に安全」ではない。エスケープが効かないのは、値を要素の中身ではなく別の意味で使う経路である。dangerouslySetInnerHTML は名前のとおり自動エスケープを迂回するので、渡す HTML のサニタイズが必須になる。hrefsrc に外部由来の文字列をそのまま入れるのも危険で、javascript: で始まる URL はクリックでスクリプトが動いてしまう。React はこのパターンを 16.9 (2019 年) で非推奨として警告するようになった (将来のメジャーリリースでエラー化する方針が当時告知されたが、2026 年 8 月時点でもエラー化は実施されておらず警告のまま)。属性をまとめて渡す props のスプレッドも、渡す側で値を検証していなければ同じ穴になる。

JSX なしの React

JSX は必須ではない。React.createElement を直接呼び出すこともできるが、可読性が大幅に低下する。

// JSX なし (冗長)
React.createElement('div', { className: 'card' },
  React.createElement('h2', null, title),
  React.createElement('p', null, description)
);

// JSX あり (簡潔)
<div className="card">
  <h2>{title}</h2>
  <p>{description}</p>
</div>

JSX vs テンプレートエンジン

JSX とテンプレートエンジンの違いを以下にまとめる。

観点JSXテンプレート (EJS, Handlebars)
言語JavaScript の拡張独自構文
型安全性TypeScript が属性名や props の型まで検査する文字列として展開され、誤りは実行時まで残る
ロジックJS の全機能が使える制限された構文
ツールIDE の補完が効く限定的
用途コンポーネント指向の UI 全般 (ブラウザ側の描画もサーバー側の描画も)サーバーで HTML 文字列を組み立てる処理

体系的に学ぶなら関連書籍を参照してほしい。

この記事は役に立ちましたか?

関連用語

関連する記事