JS.REACT.JSX.NO.LEAKED.RENDER
問題のあるリークした値がレンダリングされることを防ぐ
&&
演算子を使って JSX で条件付きで要素をレンダリングすると、予期しない値がレンダリングされたり、レンダリングがクラッシュしたりする可能性があります。
規則の詳細
この規則は、予期しない値が最終的な DOM に到達したり、レンダリングメソッドがクラッシュしたりする可能性すらもあるため、リークした危険な値がレンダリングされるのを防ぐことを目的としています。
React では、0
または NaN
のような予期しない値をレンダリングしてしまう可能性があります。React Native では、0
、''
、または NaN
をレンダリングするとレンダリングメソッドがクラッシュします:
const Example = () => {
return (
<>
{0 && <Something/>}
{/* React: renders undesired 0 */}
{/* React Native: crashes */}
{'' && <Something/>}
{/* React: renders nothing */}
{/* React Native: crashes */}
{NaN && <Something/>}
{/* React: renders undesired NaN */}
{/* React Native: crashes */}
</>
)
}
これを回避するには、次の操作を実行します:
- 条件をブール値に強制変換する: {!!someValue && <Something />}
- 二項式を、偽の値のために null
を返す三項式に変換する: {someValue ? <Something /> : null}
この規則は自動修正可能です。利用可能なさまざまな戦略の詳細については、「オプション」セクションを確認してください。
この規則で正しくないコードの例:
const Component = ({ count, title }) => {
return <div>{count && title}</div>
}
const Component = ({ count }) => {
return <div>{count && <span>There are {count} results</span>}</div>
}
const Component = ({ elements }) => {
return <div>{elements.length && <List elements={elements}/>}</div>
}
const Component = ({ nestedCollection }) => {
return (
<div>
{nestedCollection.elements.length && <List elements={nestedCollection.elements} />}
</div>
)
}
const Component = ({ elements }) => {
return <div>{elements[0] && <List elements={elements}/>}</div>
}
const Component = ({ numberA, numberB }) => {
return <div>{(numberA || numberB) && <Results>{numberA+numberB}</Results>}</div>
}
// If the condition is a boolean value, this rule will report the logical expression
// since it can't infer the type of the condition.
const Component = ({ someBool }) => {
return <div>{someBool && <Results>{numberA+numberB}</Results>}</div>
}
この規則で正しいコードの例:
const Component = ({ elements }) => {
return <div>{elements}</div>
}
// An OR condition it's considered valid since it's assumed as a way
// to render some fallback if the first value is falsy, not to render something conditionally.
const Component = ({ customTitle }) => {
return <div>{customTitle || defaultTitle}</div>
}
const Component = ({ elements }) => {
return <div>There are {elements.length} elements</div>
}
const Component = ({ elements, count }) => {
return <div>{!count && 'No results found'}</div>
}
const Component = ({ elements }) => {
return <div>{!!elements.length && <List elements={elements}/>}</div>
}
const Component = ({ elements }) => {
return <div>{Boolean(elements.length) && <List elements={elements}/>}</div>
}
const Component = ({ elements }) => {
return <div>{elements.length > 0 && <List elements={elements}/>}</div>
}
const Component = ({ elements }) => {
return <div>{elements.length ? <List elements={elements}/> : null}</div>
}
オプション
サポートされているオプションは次のとおりです:
validStrategies
"coerce"
、"ternary"
、または両方を含む配列 (デフォルト: ["ternary", "coerce"]
) - レンダリングのリークを防ぐためにどの戦略が有効と見なすかを決定します (少なくとも 1 つ必要)。「coerce」オプションは、JSX 式の条件をブール値に変換します。「Ternary」オプションは、二項式を三項式に変換し、偽の値のために null
を返します配列の最初のオプションは自動修正時に使用される戦略となるため、値の順序が重要になります。
次のように設定できます:
{
// ...
"react/jsx-no-leaked-render": [<enabled>, { "validStrategies": ["ternary", "coerce"] }]
// ...
}
次のオプションを想定します: { "validStrategies": ["ternary"] }
上記構成を含む、この規則で正しくないコードの例:
const Component = ({ count, title }) => {
return <div>{count && title}</div>
}
const Component = ({ count, title }) => {
return <div>{!!count && title}</div>
}
上記構成を含む、この規則で正しいコードの例:
const Component = ({ count, title }) => {
return <div>{count ? title : null}</div>
}
次のオプションを想定します: { "validStrategies": ["coerce"] }
上記構成を含む、この規則で正しくないコードの例:
const Component = ({ count, title }) => {
return <div>{count && title}</div>
}
const Component = ({ count, title }) => {
return <div>{count ? title : null}</div>
}
上記構成を含む、この規則で正しいコードの例:
const Component = ({ count, title }) => {
return <div>{!!count && title}</div>
}
使用してはいけない場合
常にブール条件の使用を推奨する型付きコードベースで作業している場合は、この規則を無効にすることができます。
参考文献
- React ドキュメント: Inline If with Logical && Operator (https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator)
- Good advice on JSX conditionals - Beware of zero (https://thoughtspile.github.io/2022/01/17/jsx-conditionals/)
- Twitter: rendering falsy values in React and React Native (https://twitter.com/kadikraman/status/1507654900376875011?s=21&t=elEXXbHhzWthrgKaPRMjNg)