コメント(// と /* */ と {/* */})
『React』におけるコメントの書き方です。JavaScript/TypeScript ファイルでは一行コメント(『//』)・ブロックコメント(『/* */』)・JSDoc コメント(『/** */』)が使えます。JSX の中(タグとタグの間や属性値の位置)では、これらの記法ではなく中括弧でラップした『{/* */}』を使います。HTML コメントの『』は JSX 内では使えません。
構文
// 一行コメント — // から行末までがコメントになります(JS/TS ファイル内、JSX の外側)。
const count = 0; // 行末コメント — コードの後にも書けます。
/*
ブロックコメント — /* から */ までの範囲がコメントになります。
JSX の外側の JavaScript 部分で使います。
*/
/**
* JSDoc コメント — /** で始めるブロックコメントです。
* 関数コンポーネントや関数の直前に書き、型情報や説明を記述します。
* @param props - コンポーネントの props
* @returns JSX 要素
*/
// JSX 内のコメント — 中括弧 { } でラップした /* */ を使います。
function Example() {
return (
<div>
{/* JSX 内のコメントはこの形式で書きます。 */}
<p>コンテンツ</p>
</div>
);
}
コメントの種類
| 種類 | 書き方 | 使える場所 | 概要 |
|---|---|---|---|
| 一行コメント | // テキスト | JSX の外側(JS/TS 部分) | 『//』から行末までがコメントになります。コードの右側に補足を添えるときにも使います。 |
| ブロックコメント | /* テキスト */ | JSX の外側(JS/TS 部分) | 複数行にまたがるコメントを書くときに使います。JSX 内には直接書けません。 |
| JSDoc コメント | /** テキスト */ | JSX の外側(関数・コンポーネントの直前) | 『/**』で始まる特殊なブロックコメントです。エディタや自動ドキュメントツールが解析できる形式で型や説明を記述します。 |
| JSX コメント | {/* テキスト */} | JSX の内側(タグの間・属性値位置) | 中括弧でブロックコメントをラップした形式です。JSX の返却値の中でコメントを書くときに使います。 |
JSX 内で HTML コメントが使えない理由
HTML の『』は JSX 内では使えません。JSX はブラウザに直接送られる HTML ではなく、JavaScript の関数呼び出しへと変換される構文です。コンパイラは JSX をパースする際に『』をコメントとして認識せず、構文エラーになります。
JSX 内でコメントを書く唯一の方法は『{/* */}』の形式です。中括弧は JSX 内で JavaScript 式を埋め込む構文であり、その中に JavaScript のブロックコメントを書くことでコメントとして機能します。
function Example() {
return (
<div>
<!-- これは構文エラーになります。JSX 内では HTML コメントを使えません。 -->
{/* これが正しい書き方です。中括弧の中にブロックコメントを書きます。 */}
<p>コンテンツ</p>
</div>
);
}
JSDoc の主なタグ
関数コンポーネントや hooks に JSDoc コメントを書くと、VS Code などのエディタがホバー表示でドキュメントを表示します。TypeScript を使っているプロジェクトでも、JSDoc の『@param』『@returns』でより詳しい説明を補足できます。
| タグ | 概要 |
|---|---|
| @param {型} 名前 - 説明 | 関数の引数の型と説明を記述します。TypeScript では型注釈と併用することが多いです。 |
| @returns {型} 説明 | 関数の戻り値の型と説明を記述します。コンポーネントの場合は通常 JSX.Element です。 |
| @param {型} [名前=デフォルト値] | 省略可能な props を表します。 |
| @throws エラー型 - 説明 | スローされる可能性のある例外を記述します。 |
| @example | コンポーネントや関数の使用例を記述します。 |
| @deprecated 理由 | 非推奨であることと理由を記述します。エディタが警告を表示します。 |
コメントを書くべき場所・書かなくてよい場所
| 判断 | 場面 | 理由 |
|---|---|---|
| 書くべき | 「なぜこう実装したか」の理由 | コードを読むだけではわからない設計意図やトレードオフを残しておくと、将来の自分や他の開発者が助かります。 |
| 書くべき | 複雑なアルゴリズムや計算式 | 何をしているか一見でわかりにくい処理には、動作の概要を補足します。 |
| 書くべき | 公開コンポーネント・再利用する hooks | 引数・戻り値・副作用を JSDoc で明示しておくと、呼び出し側がドキュメントを参照しなくても使えます。 |
| 書くべき | デバッグ中の一時的な無効化 | コメントアウトした理由や期限を残しておくと、後で削除し忘れるリスクが減ります。 |
| 書かなくてよい | コードを読めば明らかな処理 | 自明な説明はノイズになります。コンポーネント名・props 名をわかりやすくすれば不要になります。 |
| 書かなくてよい | 変更履歴・削除したコード | バージョン管理(git)があるため、コメントに古いコードや変更日を残す必要はありません。 |
サンプルコード
JSX 内のコメント基本形
UserCard.jsx
// JSX 外の JavaScript 部分では通常の // コメントが使えます。
/**
* ユーザー情報を表示するカードコンポーネントです。
* @param {Object} props
* @param {string} props.userName - 表示するユーザー名
* @param {string} [props.email] - メールアドレス(省略可能)
* @returns {JSX.Element}
*/
function UserCard({ userName, email }) {
// email が未指定の場合のフォールバック表示用テキスト。
const emailDisplay = email || "(未登録)";
return (
<div className="user-card">
{/* ユーザー名は必須 props のため常に表示されます。 */}
<h2>{userName}</h2>
{/* email は省略可能なので存在する場合のみ表示します。 */}
{email && <p>{email}</p>}
{/* email が未登録の場合のフォールバック表示。 */}
{!email && <p className="muted">{emailDisplay}</p>}
</div>
);
}
export default UserCard;
カスタム Hooks とコメント
useCounter.js
import { useState } from 'react';
/**
* カウンターの状態と操作を提供するカスタム Hook です。
* @param {number} [initialValue=0] - カウンターの初期値
* @returns {{ count: number, increment: Function, decrement: Function, reset: Function }}
*/
function useCounter(initialValue) {
if (initialValue === undefined) {
initialValue = 0;
}
var initialCount = initialValue;
/*
useState の初期値として関数を渡す遅延初期化パターンは、
この程度の単純な値では不要です。
複雑な計算が必要な場合は () => computeExpensiveValue() の形式を使います。
*/
var result = useState(initialCount);
var count = result[0];
var setCount = result[1];
// カウントを 1 増やします。
function increment() {
setCount(function(prev) { return prev + 1; });
}
// カウントを 1 減らします。
function decrement() {
setCount(function(prev) { return prev - 1; });
}
// カウントを初期値に戻します。
function reset() {
setCount(initialCount);
}
return { count: count, increment: increment, decrement: decrement, reset: reset };
}
export default useCounter;
CounterApp.jsx
import useCounter from './useCounter';
function CounterApp() {
var counter = useCounter(0);
return (
<div>
{/* カウンター操作ボタン。useCounter Hook で状態管理しています。 */}
<button onClick={counter.decrement}>-</button>
<span>{counter.count}</span>
<button onClick={counter.increment}>+</button>
<button onClick={counter.reset}>リセット</button>
</div>
);
}
export default CounterApp;
デバッグ用コメントアウト
DataList.jsx
import { useState, useEffect } from 'react';
function DataList() {
var stateResult = useState([]);
var items = stateResult[0];
var setItems = stateResult[1];
useEffect(function() {
fetch('/api/items')
.then(function(res) { return res.json(); })
.then(function(data) {
// デバッグ中: API レスポンスの形式を確認する(確認後に削除します)。
// console.log('API response:', data);
setItems(data);
});
/*
TODO: エラーハンドリングを追加する。
現在はネットワークエラー時に items が空のままになる問題がある(#203 参照)。
*/
}, []);
return (
<ul>
{items.map(function(item) {
return (
<li key={item.id}>
{/* item.name が空の場合は '(名称未設定)' を表示します。 */}
{item.name || '(名称未設定)'}
</li>
);
})}
</ul>
);
}
export default DataList;
概要
React では JavaScript/TypeScript の通常のコメント記法(一行コメント・ブロックコメント・JSDoc)に加え、JSX の返却値の中でコメントを書くための専用の書き方(『{/* */}』)があります。JSX 内で HTML の『』を書くと構文エラーになります。JSX はブラウザに直接送られる HTML ではなく JavaScript の関数呼び出しに変換される構文のため、コメントも JavaScript の形式で記述する必要があります。
関数コンポーネントやカスタム Hooks には JSDoc コメントを書いておくと、VS Code がホバー表示で props の型と説明を表示するようになります。チームで共有するコンポーネントライブラリでは特に効果があります。
コメントは「何をしているか」ではなく「なぜそうしているか」を書くと効果的です。コードを読めば明らかな処理を逐一コメントで説明するのはノイズになります。変更履歴や削除したコードをコメントとして残す必要もありません。それらはバージョン管理(git)で追跡できます。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。