&&を用いた条件付きレンダーにおけるfalsyな値の挙動

2024/11/28に公開

はじめまして、株式会社イルシル エンジニアの小川です。

自身で初めてのテックブログ執筆、それも実質 1 本目の記事ということで、基礎的かつ比較的軽めの内容をまとめてみました。
以前弊社チーム内のレビューで少し議論になった、条件付きレンダーに関する話題です。

&&(論理 AND 演算子)を用いた条件付きレンダー

React の UI 記述方法の 1 つに、「条件付きレンダー」があります。

様々な条件に基づいて、コンポーネントに表示させる内容を変化させたいことがあります。React では、JavaScript の if 文や &&、? : 演算子などの構文を使うことで、JSX を条件付きでレンダーできます。

引用元:条件付きレンダー - React

UI の記述に欠かせない記法の 1 つです。
中でも &&(論理 AND 演算子)を用いた条件付きレンダーは
「特定の条件を満たした場合のみレンダーしたい、それ以外はレンダーしたくない」
という場合、記述量少なく実現でき非常に便利です。
(体感 1 番使ってる気がする)

ただし、公式ドキュメントには以下の注意書きがあります。

&& の左辺に数値を置かない
JavaScript は条件をテストする際、左の辺を自動的に真偽値に変換します。しかし、左の辺が 0 の場合は、式全体がその 0 という値に評価されてしまうため、React は何もレンダーしないのではなく 0 を表示します。
たとえば、よくある間違いとして messageCount && <p>New messages</p> のようにコードを書くことが挙げられます。messageCount が 0 の場合は何も表示しないと思われがちですが、実際には 0 そのものが表示されてしまいます!
これを修正するには、左の値を真偽値にしてください: messageCount > 0 && <p>New messages</p>。

引用元:条件付きレンダー - React #論理 AND 演算子(&&)

実際、以下のようなコードは意図した挙動になりません。

カウントダウンをクリックして 0 になったら「まだ押せます」が消えて count の値が 1 つだけになって欲しいところ、
実際には条件として与えた count も表示され、0 が 2 つ表示されてしまいます。

Javascript における 0 は falsy な値のため、if 文などでは false と同様の挙動をとりますが、&&を用いた条件付きレンダーにおいては数値として扱われ、0 そのものが表示されてしまいます。

意図した挙動を目指すには、以下のように明示的に false を与える必要があります。

<div>{count > 0 && "まだ押せます"}</div>

他の falsy な値ではどうなるの?

  • &&(論理 AND 演算子)を用いた条件付きレンダーで数値の 0 はそのまま表示される
  • 表示の制御に使用したい場合はfalse へ変換する必要がある

ということが理解できました。

しかしながら、Javascript には 0false 以外にも falsy な値がたくさんあります。

  • -0 (number・数値の-0)
  • NaN(number・Not A Number)
  • 0n (bigint・整数値の 0)
  • ""(空文字)
  • null
  • undefined

それぞれを&&の左辺に渡した場合、どのような挙動をするのでしょうか??

気になったので、実際に試してみました ↓

-0NaN は自分自身がレンダーされています。
上記はどちらも falsy ではありますが 数値型 のため、0 と同様の挙動を取るようです。

""(空文字)に関しては、空文字が返されているが React(JSX)の仕様上何も表示されていない、という状態のようです。
空文字が false へ変換されているわけではないらしい
(どちらであっても表示がないことに変わりはありませんが...)

0n は bigint における整数の 0 ですが、数値型 と違ってこちらは何も表示されないようです。
どうしてこの挙動になるか色々調べましたが、明確な理由は分からずじまいでした。
有識者のコメントお待ちしております
(エラーにはならないので bigint がそもそも取り扱えない、という訳ではなさそうですが...)

nullundefined に関しても、React(JSX) 側の仕様により何もレンダーされないようです。

まとめ

&&(論理 AND 演算子)を用いた条件付きレンダーは、falsy な値の取り扱いがそれぞれ微妙に異なることがわかりました。
数値の0の取り扱いに関しては、刷新前の公式ドキュメントでは記載こそあったものの強調されていなかった内容のため、コーディングやレビューの際は気をつけたい内容です。

また、nullundefined の挙動は、正しく利用することでよりシンプルなコードを実現してくれる反面、
レビュワーや他エンジニアにコードの意図が伝わりづらくなる恐れもあるので注意が必要です。

株式会社イルシル

Discussion