🐙

`&&`を条件文の外で使うな

2024/04/16に公開
6

以下のようなコードをよく見かけます。

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

Honey32Honey32

失礼します。2の理由についてはその通り(なので、僕は remeda というライブラリで isNullish(v) && のように書きます)が、1については事実と異なっていると思います。

JS の && ||短絡評価 の挙動を示します。なので、flag && <Comp /> は、flag が false の場合、 <Comp /> が評価されません。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND#短絡評価

jay-esjay-es

右にある式も評価したうえで最後に評価した値を返します。

と書かれているので、もしかしたら「二回評価されるから遅い」と考えておられるのかも知れません。

式の評価は1度きりです(三項演算子も同じ)。
以下のようなコードを実行してみると理解の手助けになるのではないかと思います。

function test() {
  console.log("実行された");
  return 10;
}

console.log("result1 の前")
const result1 = true && test()
console.log("result1", result1)

console.log("result2 の前")
const result2 = false && test()
console.log("result2", result2)

console.log("result3 の前")
const result3 = true ? test() : null
console.log("result3", result3)

console.log("result4 の前")
const result4 = false ? test() : null
console.log("result4", result4)
108えん108えん

ありがとうございます!
「実行される」ことと「評価される」のは別の意味だと思っていますが、あってますでしょうか?
評価はされるけど、実行はされない、ただ、評価は両方されるので、ほんのちょっと遅いという認識でした。

jay-esjay-es

評価とは「コードを実行して結果を得る」ことを指すので

評価はされるけど、実行はされない

ということは起こらないと思います。

ここで && と三項演算子の挙動をまとめると、

# A && B
A を評価 → 真値なら B を評価 → B の結果の値を返す
A を評価 → 偽値なら A の結果の値を返す(B は評価されない)

# A ? B : C
A を評価 → 真値なら B を評価 → B の結果の値を返す
A を評価 → 偽値なら C を評価 → C の結果の値を返す

となり、A && B において A が偽値の場合、B の存在は無視されます。
一方で、A ? B : C で A が偽値の場合は「C の評価」というステップが発生するので、条件式が偽値の場合は && よりも三項演算子の方がむしろ

ほんのちょっと遅い

ということになるかと思います。
(もちろんナノ秒とかの単位なので無視できる範囲ですが)