JSXで予期せぬ動作を防ぐための eslint-plugin-jsx-expressions の紹介
はじめに
皆さんはJSXにてこういった条件分岐をしているコードを見た覚えはないでしょうか?
かくいう私は何度か書いた覚えが(レビューした覚えも)あります。
type Props = {
count: number;
};
const Container = ({ count }: Props) => {
return (
<div>
{count && <Counter />}
</div>
);
};
しかし上記のコードは開発者の予期せぬ不具合を含んでいます。
count
が 0
だった場合、0
がレンダーされてしまいます。(React公式ドキュメントにも記載されています)
Webの場合アプリが使えなくなるような大きなバグには繋がりませんが、React Nativeの場合アプリがクラッシュする致命的なバグにも繋がります。
こういった特定条件でのみ発生する動作はコードや目視では発見しづらいため、何らかの方法で自動的に検知したいところです。
この記事ではこのコードを検知・修正してくれる eslint-plugin-jsx-expressions について紹介します。
なぜ発生するのか
そもそもこの現象はなぜ発生するのでしょうか。
JSの論理積(&&),論理和(||)といった演算子は、短絡評価の結果の値が falsy だった場合その falsy の値をそのまま返します。(論理和(||)の場合 truthy の値)
論理積 (&&) - JavaScript | MDN
論理和 (||) - JavaScript | MDN
すなわち count && <Counter />
のような条件で count
が 0
だった場合、以下のようなコードとして解釈されます。
const Container = () => {
return (
<div>
0
</div>
);
};
この現象を回避するためには論理積の左側の判定に boolean
を使用する必要があります。
const Container = ({ count }) => {
return (
<div>
{!!count && <Counter />}
</div>
);
};
しかし、人間の注意力には限界があるので(面倒なので)ESLintで自動検知・修正をしたいところです。
eslint-plugin-jsx-expressionsの導入
このコードを検知できる eslint-plugin-jsx-expressions を導入します。
導入方法はREADMEを参照してください。
導入してエラーが発生した箇所を自動修正すると、booleanではない値を自動的にbooleanに変換するように修正してくれます。
type Props = {
count: number;
};
const Container: FC<Props> = ({ count }: Props) => {
return (
<div>
{!!count && <Counter />}
</div>
);
};
以上です。
有用なESLint Pluginを開発してくださった作者様に感謝を!
まとめ
- JSX内にて論理積で条件を記述すると予期せぬ不具合が起きうる
- eslint-plugin-jsx-expressionsを導入すると防げる
Discussion