はじめに
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
で返します。そのため、正しく条件を判定できます。
終わりに
JavaScrip
tの評価の仕組みを理解していないと、今回のように見た目には正しく見えるコードでも意図しない動作をしてしまいます。React
のJSXでは論理演算子を多用する機会が多いので、こういった評価の流れを押さえておくことが重要だと改めて感じました。
参考