no-leaked-conditional-rendering
đź’ This rule requires type information.
Rule category
Suspicious.
What it does
Prevents problematic leaked values from being rendered.
Why is this bad?
Using the &&
operator to render some element conditionally in JSX can cause unexpected values being rendered, or even crashing the rendering.
Examples
In React, you might end up rendering unexpected values like 0
or NaN
. In React Native, your render method will even crash if you render these values:
import React from "react";
function function Example(): React.JSX.Element
Example() {
return <>{0 && <React.JSX.IntrinsicElements.view: React.SVGProps<SVGViewElement>
view />}</>;
// ^
// - Possible unexpected value will be rendered (React Dom: renders undesired '0', React Native: crashes đź’Ą).
}
import React from "react";
function function Example(): React.JSX.Element
Example() {
return <>{var NaN: number
NaN && <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div />}</>;
// - Possible unexpected value will be rendered (React Dom: renders undesired 'NaN', React Native: crashes đź’Ą).
}
import React from "react";
function Example() {
return <>{"" && <div />}</>;
// ^^
// - Possible unexpected value will be rendered (React Dom: renders nothing, React Native, with React below 18: crashes đź’Ą).
}
This can be avoided by:
- coercing the conditional to a boolean:
{!!someValue && <Something />}
- transforming the binary expression into a ternary expression which returns null for falsy values:
{someValue ? <Something /> : null}
Failing
import React from "react";
interface ExampleProps {
ExampleProps.count: number
count: number;
}
function function Example({ count }: ExampleProps): React.JSX.Element
Example({ count: number
count }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{count: number
count && <React.JSX.IntrinsicElements.span: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
span>There are {count: number
count} results</React.JSX.IntrinsicElements.span: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
span>}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
// - Potential leaked value 'count' that might cause unintentionally rendered values or rendering crashes.
}
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.Element
Example({ items: string[]
items }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{items: string[]
items.Array<string>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length && <const List: React.ComponentType<{
items: string[];
}>
List items: string[]
items={items: string[]
items} />}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
// - Potential leaked value 'items.length' that might cause unintentionally rendered values or rendering crashes.
}
declare const const List: React.ComponentType<{
items: string[];
}>
List: React.type React.ComponentType<P = {}> = React.ComponentClass<P, any> | React.FunctionComponent<P>
Represents any user-defined component, either as a function or a class.
Similar to
{@link
JSXElementConstructor
}
, but with extra properties like
{@link
FunctionComponent.defaultProps defaultProps
}
.ComponentType<{ items: string[]
items: string[] }>;
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.Element
Example({ items: string[]
items }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{items: string[]
items[0] && <const List: React.ComponentType<{
items: string[];
}>
List items: string[]
items={items: string[]
items} />}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
// - Potential leaked value 'items[0]' that might cause unintentionally rendered values or rendering crashes.
}
declare const const List: React.ComponentType<{
items: string[];
}>
List: React.type React.ComponentType<P = {}> = React.ComponentClass<P, any> | React.FunctionComponent<P>
Represents any user-defined component, either as a function or a class.
Similar to
{@link
JSXElementConstructor
}
, but with extra properties like
{@link
FunctionComponent.defaultProps defaultProps
}
.ComponentType<{ items: string[]
items: string[] }>;
import React from "react";
interface ExampleProps {
ExampleProps.numberA: number
numberA: number;
ExampleProps.numberB: number
numberB: number;
}
function function Example({ numberA, numberB }: ExampleProps): React.JSX.Element
Example({ numberA: number
numberA, numberB: number
numberB }: ExampleProps) {
return (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{(numberA: number
numberA || numberB: number
numberB) && <const Results: React.ComponentType<{
children?: React.ReactNode | undefined;
}>
Results>{numberA: number
numberA + numberB: number
numberB}</const Results: React.ComponentType<{
children?: React.ReactNode | undefined;
}>
Results>}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>
// - Potential leaked value '(numberA || numberB)' that might cause unintentionally rendered values or rendering crashes.
);
}
declare const const Results: React.ComponentType<{
children?: React.ReactNode | undefined;
}>
Results: React.type React.ComponentType<P = {}> = React.ComponentClass<P, any> | React.FunctionComponent<P>
Represents any user-defined component, either as a function or a class.
Similar to
{@link
JSXElementConstructor
}
, but with extra properties like
{@link
FunctionComponent.defaultProps defaultProps
}
.ComponentType<React.type React.PropsWithChildren<P = unknown> = P & {
children?: React.ReactNode | undefined;
}
PropsWithChildren>;
Passing
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.Element
Example({ items: string[]
items }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{items: string[]
items}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
}
import React from "react";
interface ExampleProps {
ExampleProps.customTitle: string
customTitle: string;
}
const const defaultTitle: "Default Title"
defaultTitle = "Default Title";
function function Example({ customTitle }: ExampleProps): React.JSX.Element
Example({ customTitle: string
customTitle }: ExampleProps) {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 return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{customTitle: string
customTitle || const defaultTitle: "Default Title"
defaultTitle}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
}
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.Element
Example({ items: string[]
items }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>There are {items: string[]
items.Array<string>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length} items</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
}
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
ExampleProps.count: number
count: number;
}
function function Example({ items, count }: ExampleProps): React.JSX.Element
Example({ items: string[]
items, count: number
count }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{!count: number
count && "No results found"}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
}
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.Element
Example({ items: string[]
items }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{!!items: string[]
items.Array<string>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length && <const List: React.ComponentType<{
items: string[];
}>
List items: string[]
items={items: string[]
items} />}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
}
declare const const List: React.ComponentType<{
items: string[];
}>
List: React.type React.ComponentType<P = {}> = React.ComponentClass<P, any> | React.FunctionComponent<P>
Represents any user-defined component, either as a function or a class.
Similar to
{@link
JSXElementConstructor
}
, but with extra properties like
{@link
FunctionComponent.defaultProps defaultProps
}
.ComponentType<{ items: string[]
items: string[] }>;
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.Element
Example({ items: string[]
items }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{var Boolean: BooleanConstructor
<number>(value?: number | undefined) => boolean
Boolean(items: string[]
items.Array<string>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length) && <const List: React.ComponentType<{
items: string[];
}>
List items: string[]
items={items: string[]
items} />}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
}
declare const const List: React.ComponentType<{
items: string[];
}>
List: React.type React.ComponentType<P = {}> = React.ComponentClass<P, any> | React.FunctionComponent<P>
Represents any user-defined component, either as a function or a class.
Similar to
{@link
JSXElementConstructor
}
, but with extra properties like
{@link
FunctionComponent.defaultProps defaultProps
}
.ComponentType<{ items: string[]
items: string[] }>;
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.Element
Example({ items: string[]
items }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{items: string[]
items.Array<string>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length > 0 && <const List: React.ComponentType<{
items: string[];
}>
List items: string[]
items={items: string[]
items} />}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
}
declare const const List: React.ComponentType<{
items: string[];
}>
List: React.type React.ComponentType<P = {}> = React.ComponentClass<P, any> | React.FunctionComponent<P>
Represents any user-defined component, either as a function or a class.
Similar to
{@link
JSXElementConstructor
}
, but with extra properties like
{@link
FunctionComponent.defaultProps defaultProps
}
.ComponentType<{ items: string[]
items: string[] }>;
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.Element
Example({ items: string[]
items }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{items: string[]
items.Array<string>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length ? <const List: React.ComponentType<{
items: string[];
}>
List items: string[]
items={items: string[]
items} /> : null}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
}
declare const const List: React.ComponentType<{
items: string[];
}>
List: React.type React.ComponentType<P = {}> = React.ComponentClass<P, any> | React.FunctionComponent<P>
Represents any user-defined component, either as a function or a class.
Similar to
{@link
JSXElementConstructor
}
, but with extra properties like
{@link
FunctionComponent.defaultProps defaultProps
}
.ComponentType<{ items: string[]
items: string[] }>;
import React from "react";
interface ExampleProps {
ExampleProps.items: string[]
items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.Element
Example({ items: string[]
items }: ExampleProps) {
return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{items: string[]
items.Array<string>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length ? <const List: React.ComponentType<{
items: string[];
}>
List items: string[]
items={items: string[]
items} /> : <const EmptyList: React.ComponentType<{}>
EmptyList />}</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>;
}
declare const const List: React.ComponentType<{
items: string[];
}>
List: React.type React.ComponentType<P = {}> = React.ComponentClass<P, any> | React.FunctionComponent<P>
Represents any user-defined component, either as a function or a class.
Similar to
{@link
JSXElementConstructor
}
, but with extra properties like
{@link
FunctionComponent.defaultProps defaultProps
}
.ComponentType<{ items: string[]
items: string[] }>;
declare const const EmptyList: React.ComponentType<{}>
EmptyList: React.type React.ComponentType<P = {}> = React.ComponentClass<P, any> | React.FunctionComponent<P>
Represents any user-defined component, either as a function or a class.
Similar to
{@link
JSXElementConstructor
}
, but with extra properties like
{@link
FunctionComponent.defaultProps defaultProps
}
.ComponentType;