Reactの強力な機能の一つである条件付きレンダーは、JSXの内部でJavaScriptの表現力を最大限に活用することで実現されています。
本記事では、この条件付きレンダーを実現する主要な3つのテクニック
①if文による早期リターン
②論理AND演算子 (&&) によるインライン表示制御
③三項演算子 (? :) によるインライン if-else—
の具体的な書き方と、Reactで使う際の注意点を実例を交えて解説しています。
条件付きレンダーとは何か?
Reactにおける条件付きレンダーとは、状態(state)やプロパティ(props)など値や条件に応じて、表示する要素(JSX)を切り替える仕組みのことです。
条件付きレンダーを使うことで、「ユーザーがログインしていたらログアウトボタンを表示し、ログインしていなかったらログインボタンを表示する」といった、動的なUI(ユーザーインターフェース)を実現できます。
主な手法として、if文、論理AND演算子(&&)、条件演算子(三項演算子: ? :)を使います。
Reactの基本、コンポーネント、JSX、Propsとは何かについては下記をご参考ください。
>【React】コンポーネントとは何か?基本を実例で解説(注意点、export defaultとimport from)
> 【React】JSXとは何か?特徴や注意点を実例で解説(className, htmlFor, onClick, 変数・式・関数の呼び出し)
if文による条件分岐
実例
JSXではJavaScriptのif文を使うことができます。
// ログイン状態を受け取るコンポーネント
function UserGreeting(props) {
const isLoggedIn = props.isLoggedIn; // ログイン状態(true/false)
// 1. 条件が true の場合
if (isLoggedIn) {
// ログイン済みの場合の表示を返却
return <h1>おかえりなさい!</h1>;
}
// 2. 条件が false の場合の表示を返却 (else の役割)
return <h1>ログインしてください。</h1>;
}
// 例: <UserGreeting isLoggedIn={true} /> の場合、"おかえりなさい!" が表示されます。コンポーネントではreturnで戻り値を指定します。このため、elseを記載しなくても、falseの場合は次の処理に移ります。
nullで可読性を上げる
複雑なコンポーネントでは、すべてのコードをif/elseブロックで囲むよりも、まず「表示しない(nullを返す)」などの特定の条件を早期リターンで処理してしまう方が、コードがシンプルで読みやすくなります。
// 例: データがない場合は何も表示しない(早期リターンで null を返す)
function Post({ data }) {
if (!data) { // data が null や undefined の場合
return null; // ★何もレンダーしない
}
// データがある場合のみ、以下の処理を実行
return (
<div className="post">
<h2>{data.title}</h2>
<p>{data.content}</p>
{/* ... その他の要素 ... */}
</div>
);
}論理AND演算子 (&&)による条件分岐
論理AND演算子 (&&)を使うと、「条件がtrueのときだけ要素を表示し、falseのときは何も表示しない」という、切り替えをすることができます。
以下の場合、条件がtureならコードを返します。falseの場合は何もしません。
条件 && コード実例
function ItemList(props) {
const isPacked = props.isPacked;
const itemName = props.name;
return (
<li className="item">
{itemName}
{isPacked && ' ✅'} //isPacked=trueの場合のみ✅を表示
</li>
);
}
// 例: <ItemList name="牛乳" isPacked={true} /> → 牛乳 ✅
// 例: <ItemList name="卵" isPacked={false} /> → 卵注意点:タグの分割はできない
JSXでは必ず閉じタグが必要です。開始タグと終了タグを分割して記述することはできません。
このため、次の記述はエラーが出ます。
//変数importanceが0以上の場合に、nameをイタリックで出力する
function Item({ name, importance }) {
return (
<li className="item">
{importance >0 && <i>}{name}{importance >0 && </i>}
</li>
);
}JSXがパースするときに、閉じタグのないiタグを描画しようとした時点でエラーが発生します。
上記を実現したいときは以下のように書き換える必要があります。
function Item({ name, importance }) {
return (
<li className="item">
{importance > 0
? <i>{name}</i> // importance > 0 の場合
: name // importance が 0 またはそれ以下の場合
}
</li>
);
}補足:JavaScriptの短絡評価(Short-circuit evaluation)
論理AND演算子 (&&)による条件分岐は、ReactやJSX特有のものではなく、JavaScriptの短絡評価を利用したものです。
const isLogin = true;
const message1 = isLogin && 'ようこそ!';
console.log(message1); // 出力: "ようこそ!"
const isCartEmpty = false;
const message2 = isCartEmpty && 'カートは空です。';
console.log(message2); // 出力: falseReactと異なる挙動としては、JavaScriptの場合、条件がtrue以外の場合は、条件の結果をそのまま返します。
JavaScriptでは、ブール値のfalse以外にも、条件式の中でfalseと同じように扱われる特別な値があります。これらをFalsyな値と呼び、以下の6種類があります。
false(ブール値)0(数値のゼロ)""または''(空文字列)nullundefinedNaN(Not a Number)
例えば、以下のようになります。
| 式 | 返される値 | 値の型 |
false && ' ✅' | false | boolean |
0 && ' ✅' | 0 | number |
"" && ' ✅' | "" | string |
null && ' ✅' | null | object |
条件演算子 (三項演算子)による条件分岐
条件演算子とは何か?
条件演算子(三項演算子)を使うことで、条件がtrueのときとfalseのときで、異なる2つの要素を必ず出し分けることができます。
条件演算子は「?」と「:」を使って以下のように記述します。
条件式 ? trueの場合の式 : falseの場合の式条件演算子と三項演算子は同じものを指します。別名です。
注意点
三項演算子は、if-else文のようにどちらか一方を必ず表示したいときに使います。
入れ子にすると可読性が著しく低下するため、複雑な条件分岐には向いていません。複雑な場合はif文や後述の要素変数を使用が推奨です。
条件演算子の実例
function LoginButton(props) {
const isLoggedIn = props.isLoggedIn; // ログイン状態
//isLoggedIn が true なら "ログアウト" ボタン、false なら "ログイン" ボタンを表示
return (
<div>
{isLoggedIn ? <button>ログアウト</button> : <button>ログイン</button>}
</div>
);
}丸カッコ ( ) は必要?
条件演算子を記述する場合に、 条件の後に( )が付く場合があります。
結論的には、なくても動きますが、あった方がコードがわかりやすくなります。また、JavaScriptが改行時に自動的に「;」をつける自動セミコロン挿入 (ASI)機能による誤作動を防ぐことができます。
これらの理由により丸カッコ () の挿入が強く推奨されます。
丸カッコなしの場合
return (
<div>
{isLoggedIn ? <button>ログアウト</button> : <button>ログイン</button>}
</div>
);丸カッコありの場合
return (
<div>
{isLoggedIn ? (
<button>ログアウト</button> // trueのブロック
) : (
<button>ログイン</button> // falseのブロック
)}
</div>
);改行時に、真の場合の処理と、偽の場合の処理がどこまでかがわかりやすくなります。
複数のタグを返す場合
複数のタグを返す場合も、丸カッコをつけることで可読性が上がります。
return (
<div>
{isLoggedIn ? (
<>
<p>ようこそ!</p> {/* 1つ目の要素 */}
<button>ログアウト</button> {/* 2つ目の要素 */}
</>
) : (
<button>ログイン</button>
)}
</div>
);注意点:{ }はタグの中でのみ必要
JSXにおいて、タグの中でJavaScriptの変数や式、関数を使いたい場合は波カッコ{ }を使います。
こうすることで、{}の中がJavaScriptの空間になります。その中で{}をつけるとプロパティを記述することができます。
逆に言うと、二重カッコをつけるとプロパティ以外の場合はエラーになります。このため以下の条件演算子はエラーとなります。
function Item({ name, importance }) {
return (
<li className="item">
{importance > 0 ? <i>{name}</i> : {name}}
</li>
);
}
export default function PackingList() {
return (
<section>
<h1>Sally Ride's Packing List</h1>
<Item
importance={9}
name="Space suit"
/>
</section>
);
}
//出力
Error
Objects are not valid as a React child (found: object with keys {name}). If you meant to render a collection of children, use an array instead.
これはimportanceが0以上のときは、nameをイタリックで返し、それ以外のときは通常のテキストで返す記述です。
この条件演算子自体はliタグで囲まれているため{}をつけています。そのうえで、真の場合の処理は更にiタグで囲むため{}をつける必要があります。
一方、偽の場合はタグで囲んでいないのに{}をつけているため、プロパティとみなされてしまいます。
{importance > 0 ? <i>{name}</i> : {name}}ですが、name自体はプロパティではなくただのテキストなので、エラーとなります。
正しくは以下のように記述する必要があります。
{importance > 0 ? <i>{name}</i> : name }これは()をつけた以下と同じです。
{importance > 0 ?(
<i>{name}</i>
):(
name
)}

