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.ElementExample() {
return <>{0 && <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.ElementExample() {
return <>{var NaN: numberNaN && <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 function Example(): React.JSX.ElementExample() {
return <>{"" && <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>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: numbercount: number;
ExampleProps.title: stringtitle: string;
}
function function Example({ count, title }: ExampleProps): React.JSX.ElementExample({ count: numbercount, title: stringtitle }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{count: numbercount && title: stringtitle}</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>;
// - Potential leaked value that might cause unintentionally rendered values or rendering crashes.
}import React from "react";
interface ExampleProps {
ExampleProps.count: numbercount: number;
}
function function Example({ count }: ExampleProps): React.JSX.ElementExample({ count: numbercount }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{count: numbercount && <JSX.IntrinsicElements.span: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>span>There are {count: numbercount} results</JSX.IntrinsicElements.span: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>span>}</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>;
// - Potential leaked value 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.ElementExample({ items: string[]items }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{items: string[]items.Array<string>.length: numberGets 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} />}</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>;
// - Potential leaked value 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
}
and
{@link
ComponentClass.contextTypes
contextTypes
}
.ComponentType<{ items: string[]items: string[] }>;import React from "react";
interface ExampleProps {
ExampleProps.items: string[]items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.ElementExample({ items: string[]items }: ExampleProps) {
return <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} />}</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>;
// - Potential leaked value 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
}
and
{@link
ComponentClass.contextTypes
contextTypes
}
.ComponentType<{ items: string[]items: string[] }>;import React from "react";
interface ExampleProps {
ExampleProps.numberA: numbernumberA: number;
ExampleProps.numberB: numbernumberB: number;
}
function function Example({ numberA, numberB }: ExampleProps): React.JSX.ElementExample({ numberA: numbernumberA, numberB: numbernumberB }: ExampleProps) {
return (
<JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{(numberA: numbernumberA || numberB: numbernumberB) && <const Results: React.ComponentType<{
children?: React.ReactNode | undefined;
}>
Results>{numberA: numbernumberA + numberB: numbernumberB}</const Results: React.ComponentType<{
children?: React.ReactNode | undefined;
}>
Results>}</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>
// - Potential leaked value 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
}
and
{@link
ComponentClass.contextTypes
contextTypes
}
.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.ElementExample({ items: string[]items }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{items: string[]items}</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>;
}import React from "react";
interface ExampleProps {
ExampleProps.customTitle: stringcustomTitle: string;
}
const const defaultTitle: "Default Title"defaultTitle = "Default Title";
function function Example({ customTitle }: ExampleProps): React.JSX.ElementExample({ customTitle: stringcustomTitle }: 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 <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{customTitle: stringcustomTitle || const defaultTitle: "Default Title"defaultTitle}</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.ElementExample({ items: string[]items }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>There are {items: string[]items.Array<string>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.length} items</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>;
}import React from "react";
interface ExampleProps {
ExampleProps.items: string[]items: string[];
ExampleProps.count: numbercount: number;
}
function function Example({ items, count }: ExampleProps): React.JSX.ElementExample({ items: string[]items, count: numbercount }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{!count: numbercount && "No results found"}</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.ElementExample({ items: string[]items }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{!!items: string[]items.Array<string>.length: numberGets 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} />}</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
}
and
{@link
ComponentClass.contextTypes
contextTypes
}
.ComponentType<{ items: string[]items: string[] }>;import React from "react";
interface ExampleProps {
ExampleProps.items: string[]items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.ElementExample({ items: string[]items }: ExampleProps) {
return <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: numberGets 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} />}</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
}
and
{@link
ComponentClass.contextTypes
contextTypes
}
.ComponentType<{ items: string[]items: string[] }>;import React from "react";
interface ExampleProps {
ExampleProps.items: string[]items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.ElementExample({ items: string[]items }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{items: string[]items.Array<string>.length: numberGets 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} />}</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
}
and
{@link
ComponentClass.contextTypes
contextTypes
}
.ComponentType<{ items: string[]items: string[] }>;import React from "react";
interface ExampleProps {
ExampleProps.items: string[]items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.ElementExample({ items: string[]items }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{items: string[]items.Array<string>.length: numberGets 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}</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
}
and
{@link
ComponentClass.contextTypes
contextTypes
}
.ComponentType<{ items: string[]items: string[] }>;import React from "react";
interface ExampleProps {
ExampleProps.items: string[]items: string[];
}
function function Example({ items }: ExampleProps): React.JSX.ElementExample({ items: string[]items }: ExampleProps) {
return <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>{items: string[]items.Array<string>.length: numberGets 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 />}</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
}
and
{@link
ComponentClass.contextTypes
contextTypes
}
.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
}
and
{@link
ComponentClass.contextTypes
contextTypes
}
.ComponentType;