react-perf/jsx-no-jsx-as-prop
Disallow JSX elements created during render as the value of a JSX prop
Also called react_perf/jsx-no-jsx-as-prop
JSX written inside a component makes a new element object on every render. When you pass it as a prop, it's never equal to the value from the last render, so a child wrapped in React.memo renders again even though nothing changed.
JSX at the top level of a module isn't reported, because it's created once.
Configure#
Off by default. To turn it on:
[lint.rules]
"react-perf/jsx-no-jsx-as-prop" = "error" # or "warn"Every option, set to its default:
[lint.rules]
"react-perf/jsx-no-jsx-as-prop" = ["error", {
nativeAllowList = [], # list of strings
}]Examples#
function Toolbar() {
return <Button icon={<SaveIcon />JSX attribute values should not contain other JSX.} />;
}The rule looks into ||, &&, ?? and ? ::
function Toolbar({ dirty }) {
return <Button icon={dirty ? <SaveIcon />JSX attribute values should not contain other JSX. : null} />;
}A variable declared inside the component has the same problem as JSX written in the prop. The report is on the declaration:
function Toolbar() {
const iconJSX attribute values should not contain other JSX. = <SaveIcon />;
return <Button icon={icon} />;
}const saveIcon = <SaveIcon />;
function Toolbar() {
return <Button icon={saveIcon} />;
}If the element depends on props or state, cache it with useMemo:
import { useMemo } from "react";
function Toolbar({ color }) {
const icon = useMemo(() => <SaveIcon color={color} />, [color]);
return <Button icon={icon} />;
}Options#
| Option | Default | What it does |
|---|---|---|
nativeAllowList | [] | Props to skip on elements with a lowercase name, such as <div>. A list of prop names (case doesn't matter), or "all" for every prop. |
With { "nativeAllowList": ["header"] }, this is allowed:
{ "nativeAllowList": ["header"] }No problemsfunction Page() {
return <my-card header={<Title />} />;
}Components are still checked:
{ "nativeAllowList": ["header"] }1 problemfunction Page() {
return <Card header={<Title />JSX attribute values should not contain other JSX.} />;
}When not to use it#
A new prop value only matters to a child that compares its props, for example with React.memo. The React Compiler memoizes these values for you.