こんにちは、かつコーチです。
前回はViteを使ってReactの開発環境を作りました。
src/App.tsxを開くと、HTMLのようなタグがJavaScriptの中に書かれていて、「これは一体何の記法なんだろう」と感じた人もいるはずです。
今回は、そのReact特有の書き方であるJSXについて解説していきます。
JSXとは?
HTMLに似ているが別物の記法
JSX(JavaScript XML)とは、JavaScriptの中にHTMLのようなタグを直接書けるようにする拡張記法です。
function App() {
return (
<div>
<h1>こんにちは、かつコーチです</h1>
<p>Reactの学習を始めましょう</p>
</div>
);
}
見た目はほぼHTMLですが、JSXはあくまでJavaScriptの構文であり、最終的にはJavaScriptの関数呼び出しに変換されます。
先ほどのコードは、裏側では次のようなJavaScriptに変換されて実行されています。
function App() {
return React.createElement(
"div",
null,
React.createElement("h1", null, "こんにちは、かつコーチです"),
React.createElement("p", null, "Reactの学習を始めましょう")
);
}
React.createElementを毎回手で書くのは大変なので、代わりに「HTMLっぽい書き方」をできるようにしたのがJSXだと理解しておいてください。
なぜJSXという書き方が生まれたのか
Reactの開発チームは、「見た目(UI)」と「そのロジック」を分けるのではなく、あえて一緒に書くという設計を選びました。
一見すると、HTMLとJavaScriptを分離してきたこれまでの常識に反するように感じるかもしれません。
ですが、「この部品はどんな見た目で、どう動くか」を1つのファイルにまとめて書けることで、コンポーネント単位での見通しがよくなるというメリットがあります。
JSXとHTMLの違い
classではなくclassNameを使う
JSXは見た目はHTMLとそっくりですが、いくつか重要な違いがあります。
最初につまずきやすいのが、CSSのクラスを指定するときの書き方です。
❌ Before:HTMLと同じ感覚でclass属性を書いてしまう
function App() {
return <div class="container">こんにちは</div>;
}
これは一見動きそうに見えますが、TypeScript環境では型エラーになり、正しく認識されません。
classはJavaScriptの予約語(クラス構文で使われる単語)と衝突するため、JSXでは使えないルールになっています。
✅ After:className属性を使う
function App() {
return <div className="container">こんにちは</div>;
}
私も最初のうちは無意識にHTMLの感覚でclassと書いてしまい、エディタに赤い波線が出て「あれ、何がおかしいんだ?」と数分悩んだことがあります。
「JSXではclassNameを使う」というルールは最初のうちに覚えてしまうのが一番の近道です。
属性名はキャメルケースで書く
もう1つの違いは、属性名の書き方です。
HTMLではonclickのようにすべて小文字で書きますが、JSXではonClickのようにキャメルケース(単語の区切りを大文字にする書き方)で書きます。
function App() {
const handleClick = () => {
alert("クリックされました");
};
return <button onClick={handleClick}>押してね</button>;
}
onclickと小文字で書いてしまうと反応しないので、こちらも注意が必要です。
JSXの中にJavaScriptの値を埋め込む
波かっこ{ }で変数や式を書く
JSXの大きな特徴は、{ }(波かっこ)で囲むことでJavaScript・TypeScriptの変数や式をそのまま埋め込める点です。
function App() {
const userName: string = "かつコーチ";
const age: number = 30;
return (
<div>
<p>こんにちは、{userName}さん</p>
<p>年齢は{age}歳です</p>
<p>来年は{age + 1}歳になります</p>
</div>
);
}
{userName}のように変数を埋め込むだけでなく、{age + 1}のように計算式をそのまま書くこともできます。
この「HTMLっぽい見た目の中に、動的な値を自由に差し込める」という点が、JSXの一番の強みです。
条件によって表示を変える
{ }の中には、三項演算子や&&演算子を使った条件分岐もよく書かれます。
function App() {
const isLoggedIn: boolean = true;
return (
<div>
{isLoggedIn ? <p>ようこそ、かつコーチさん</p> : <p>ログインしてください</p>}
</div>
);
}
isLoggedInがtrueなら「ようこそ」、falseなら「ログインしてください」が表示されます。
JSXの中ではif文をそのまま書くことはできないため、三項演算子で条件分岐を表現するのが一般的な書き方です。
JSXを書くときのルール
ルート要素は1つにまとめる
JSXでは、returnの中に複数の要素を並べて書くことができません。
❌ Before:複数の要素を並べて返してしまう
function App() {
return (
<h1>タイトル</h1>
<p>本文</p>
);
}
このコードはコンパイルエラーになります。
✅ After:1つの親要素で囲む
function App() {
return (
<div>
<h1>タイトル</h1>
<p>本文</p>
</div>
);
}
「余計な<div>を増やしたくない」という場合は、<>と</>で囲むフラグメントという書き方も使えます。
function App() {
return (
<>
<h1>タイトル</h1>
<p>本文</p>
</>
);
}
見た目に影響を与えたくないときは、こちらのフラグメントを使うのがおすすめです。
まとめ
この記事のポイント
- JSXはJavaScriptの中にHTMLのようなタグを書ける拡張記法で、最終的にJavaScriptの関数呼び出しに変換される
classではなくclassName、属性名はキャメルケースで書く{ }で囲むことで、変数・計算式・条件分岐などJavaScript・TypeScriptの値を埋め込めるreturnの中は1つの親要素にまとめる必要があり、フラグメント(<>)で余計なタグを避けられる
次に読むべき記事
JSXの基本が分かったところで、次回はいよいよReactの中心概念である「コンポーネント」の作り方を解説します。
→ 次の記事:コンポーネントとは?関数コンポーネントの作り方