はじめに
Reactで複数の条件を使って表示の出し分けをしようとした際に、思わぬ落とし穴にはまってしまいました。今回はその間違いと正しい書き方についてまとめます。
この記事は個人的なアウトプットを目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです。
間違えた方法
propsとして渡されたtypeの値によって、子コンポーネントの表示・非表示を切り替える処理をしていました。最初に書いたコードはこちらです。
<Components type="typeA" />
const Components = ({ type }) => {
return <>{type === "typeA" || "typeB" || "typeC" && <SomeComponent />}</>;
};
このコードでは、typeがtypeA, typeB, typeC のいずれかのときに<SomeComponent />を表示しようとしました。しかし、実際の挙動は意図通りになりませんでした。
-
type = "typeA"のとき:何も表示されない -
type = "typeB"のとき:typeBという文字列が表示される -
type = "typeC"のとき:同様にtypeBが表示される
JavaScriptがどのように評価しているのか?
この式をJavaScriptがどう評価してるか、分解していきます。
{type === "typeA" || "typeB" || "typeC" && <SomeComponent />}
まず、演算子の優先順位と評価順序が重要です:
type === "typeA" // これは true または false になる
type = "typeA"のとき:
true || "b" || "c" && <SomeComponent />
このとき、最初のtrueで評価が完了してしまうため、Reactはtrueをレンダリングしようとして、結果何も表示されません。
type = "typeB"、type = "type C"のとき:
type === "typeA" // ここはfalseになる
typeAはfalseになるので||の評価に移ります。
false || "typeB" || "typeC" && <SomeComponent />
typeBがtrueになるので"typeC" && <SomeComponent />は評価されずに終了します。typeBが文字列として表示されます。
正しい実装方法
このようなケースでは、配列とincludesメソッドを使うことで、意図通りの条件分岐が可能になります。
{["a", "b", "c"].includes(type) && <SomeComponent />}
includesは、配列に指定した値が含まれているかどうかをtrue/falseで返します。そのため、正しく条件を判定できます。
終わりに
JavaScriptの評価の仕組みを理解していないと、今回のように見た目には正しく見えるコードでも意図しない動作をしてしまいます。ReactのJSXでは論理演算子を多用する機会が多いので、こういった評価の流れを押さえておくことが重要だと改めて感じました。
参考
