JSX(TSX)内で条件分岐させたい
map関数内で配列内の値によって条件分岐させたい
勉強しながらWebサイトを作成していて条件分岐の方法がよくわからずしばらく迷ったので振り返りも兼ねて書いています
やりたかったこと
- リストの項目を連想配列にしてmap関数で繰り返す
- そのとき、特定のアイコンのみ項目名の末尾に表示させたい
- リストの項目は他でも使用しているので変えたくない
使用しているもの
方法
論理 AND 演算子を使用
A && B
左辺(A)が真値の場合は右辺(B)の値を返し、左辺が偽値の場合は左辺の値を返す
ただしReactはfalseを無視して飛ばすので、左辺がfalseの場合は何も返らない
mdn web docs 論理積(&&) より引用
論理積 (&&) はオペランドを左から右に向けて評価し、遭遇した最初の偽値のオペランドを直ちに返します。すべての値が真値であった場合、最後のオペランドの値が返されます。
ある値が true に変換できる場合、その値は真値 (truthy) と呼ばれます。ある値が false に変換できる場合、その値は偽値 (falsy) と呼ばれます。
false に変換することができる式の例を示します。
- false
- null
- NaN
- 0
- 空文字列 ("" または '' または ``)
- undefined
これらはfalseとして扱われるため、左辺(A)がこれらだった場合はこの値が返る
ただし0の場合はReactに無視されないため0が返るので左辺は条件式にすると良い
実際にやってみる
まず連想配列で項目の中身を作る
挨拶リストにしてみます
const greeting = [
{
text: "Hello World",
icon: GlobeAsiaAustraliaIcon,
},
{
text: "Hello Everyone",
icon: HandRaisedIcon,
},
];
次にmap関数内に繰り返したい項目を入れる
とりあえずそのままアイコンを表示させてみる
export default function App() {
return (
<ul>
{greeting.map((item) => (
<li key={item.text}>
{item.text}
<item.icon />
</li>
))}
</ul>
);
}
結果
両方にアイコンが表示された
CSS等は何もあてていないのでそのまんまです
このとき、アイコンが手のひら(HandRaisedIcon)の場合のみ表示させたい
export default function App() {
return (
<ul>
{greeting.map((item) => (
<li key={item.text}>
{item.text}
{item.icon === HandRaisedIcon && (<item.icon />)}
</li>
))}
</ul>
);
}
左辺item.icon === HandRaisedIcon
がtrueのとき左辺<item.icon/>
の値を返す
地球のアイコンが消えて手のひらのアイコンのみ表示された
三項演算子でもできる
今回はtrueの場合のみ表示させたかったので上記の方法で十分だったけど三項演算子でもできました
greeting.map((item) => (
<li key={item.text}>
{item.text}
{item.icon === HandRaisedIcon ? (
<item.icon />
) : null}
</li>
))
何に引っかかっていたのか
- 条件分岐なのだからif文を使えばよいだろうと単純に考えていたが、JSX内にif...else文は直接かけない なんてこった
- map関数内で分岐させたかったがそもそもの理解が乏しいため1が原因であるとわからなかった
まとめ
今回こうしてまとめるために振り返ってみると、ReactのドキュメントやMDN Web Docsにちゃんと書いてありますね……
ドキュメントは何度でもしっかり読もう 反省
参考
条件付きレンダー
https://ja.react.dev/learn/conditional-rendering
論理積 (&&)
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND
if文はJSXの中で書け
https://qiita.com/horiy0125/items/fa07f5baa6028b9746ce