🐙
`&&`を条件文の外で使うな
以下のようなコードをよく見かけます。
const [flag, setFlag] = useState<boolean>(false)
...
return (
<>
{flag && <Component />}
</>
)
&&を使った<Component />の表示切替、スマートでカッコいいですよね。
今回はこれまあまり推奨されないという話を書きます。
理由
今回はflagがboolean型のため問題ありませんが、boolean以外である場合、それがそのまま画面に描画されてしまう場合があります。
例えば、以下の場合、描画されるのは0です。
return (
<>
{0 && <Component />}
</>
)
まとめ
タイトルには使うなと強めに書きましたが、特に理由がない場合は三項演算子を使いましょう。
どうしても&&でやらないといけない場合は、仕様をちゃんと理解したうえで利用しましょう。
const [flag, setFlag] = useState<boolean>(false)
...
return (
<>
- {flag && <Component />}
+ {flag ? <Component /> : null}
</>
)
補足
flagが数値の場合でも無理やりやろうとすると、以下のように!!をつけるとできます。
const [flag, setFlag] = useState<number>(0)
...
return (
<>
{!!flag && <Component />}
</>
)
それか、こう
{flag !== 0 && <Component />}
Discussion
失礼します。2の理由についてはその通り(なので、僕は remeda というライブラリで
isNullish(v) &&のように書きます)が、1については事実と異なっていると思います。JS の
&&||は 短絡評価 の挙動を示します。なので、flag && <Comp />は、flagが false の場合、<Comp />が評価されません。ありがとうございます!
と書かれているので、もしかしたら「二回評価されるから遅い」と考えておられるのかも知れません。
式の評価は1度きりです(三項演算子も同じ)。
以下のようなコードを実行してみると理解の手助けになるのではないかと思います。
ありがとうございます!
「実行される」ことと「評価される」のは別の意味だと思っていますが、あってますでしょうか?
評価はされるけど、実行はされない、ただ、評価は両方されるので、ほんのちょっと遅いという認識でした。
評価とは「コードを実行して結果を得る」ことを指すので
ということは起こらないと思います。
ここで
&&と三項演算子の挙動をまとめると、となり、
A && Bにおいて A が偽値の場合、B の存在は無視されます。一方で、
A ? B : Cで A が偽値の場合は「C の評価」というステップが発生するので、条件式が偽値の場合は&&よりも三項演算子の方がむしろということになるかと思います。
(もちろんナノ秒とかの単位なので無視できる範囲ですが)
なるほど、勉強になりました!ありがとうございます!
(下の方にもかいてありました...)