fix(linter/react_perf): allow new objects, array, fns, etc in top scope (#4395)

Consider the following code:
```tsx
import { FC } from 'react'
import { SvgIcon } from '@mui/material'

const StyledIcon = <SvgIcon sx={{ padding: 1, color: '#ff0000' }} />
//          reported violation  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
export const MyComponent: FC = () => {
    return (
        <div>
            {StyledIcon}
            {/* ... */}
        </div>
    )
}
```

This should not be a violation since the JSX is pre-computed and re-used, which
does not break React's `Object.is()` checks.
This commit is contained in:
DonIsaac 2024-07-23 01:39:07 +00:00
parent 00c7b7dad4
commit ac08de817e
9 changed files with 162 additions and 119 deletions

View file

@ -38,6 +38,9 @@ declare_oxc_lint!(
impl Rule for JsxNoJsxAsProp {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if node.scope_id() == ctx.scopes().root_scope_id() {
return;
}
if let AstKind::JSXElement(jsx_elem) = node.kind() {
check_jsx_element(jsx_elem, ctx);
}
@ -81,14 +84,21 @@ fn check_expression(expr: &Expression) -> Option<Span> {
fn test() {
use crate::tester::Tester;
let pass = vec![r"<Item callback={this.props.jsx} />"];
let fail = vec![
let pass = vec![
r"<Item callback={this.props.jsx} />",
r"const Foo = () => <Item callback={this.props.jsx} />",
r"<Item jsx={<SubItem />} />",
r"<Item jsx={this.props.jsx || <SubItem />} />",
r"<Item jsx={this.props.jsx ? this.props.jsx : <SubItem />} />",
r"<Item jsx={this.props.jsx || (this.props.component ? this.props.component : <SubItem />)} />",
];
let fail = vec![
r"const Foo = () => (<Item jsx={<SubItem />} />)",
r"const Foo = () => (<Item jsx={this.props.jsx || <SubItem />} />)",
r"const Foo = () => (<Item jsx={this.props.jsx ? this.props.jsx : <SubItem />} />)",
r"const Foo = () => (<Item jsx={this.props.jsx || (this.props.component ? this.props.component : <SubItem />)} />)",
];
Tester::new(JsxNoJsxAsProp::NAME, pass, fail).with_react_perf_plugin(true).test_and_snapshot();
}

View file

@ -46,6 +46,9 @@ declare_oxc_lint!(
impl Rule for JsxNoNewArrayAsProp {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if node.scope_id() == ctx.scopes().root_scope_id() {
return;
}
if let AstKind::JSXElement(jsx_elem) = node.kind() {
check_jsx_element(jsx_elem, ctx);
}
@ -103,9 +106,9 @@ fn check_expression(expr: &Expression) -> Option<Span> {
fn test() {
use crate::tester::Tester;
let pass = vec![r"<Item list={this.props.list} />"];
let fail = vec![
let pass = vec![
r"<Item list={this.props.list} />",
r"const Foo = () => <Item list={this.props.list} />",
r"<Item list={[]} />",
r"<Item list={new Array()} />",
r"<Item list={Array()} />",
@ -114,6 +117,15 @@ fn test() {
r"<Item list={this.props.list || (this.props.arr ? this.props.arr : [])} />",
];
let fail = vec![
r"const Foo = () => (<Item list={[]} />)",
r"const Foo = () => (<Item list={new Array()} />)",
r"const Foo = () => (<Item list={Array()} />)",
r"const Foo = () => (<Item list={this.props.list || []} />)",
r"const Foo = () => (<Item list={this.props.list ? this.props.list : []} />)",
r"const Foo = () => (<Item list={this.props.list || (this.props.arr ? this.props.arr : [])} />)",
];
Tester::new(JsxNoNewArrayAsProp::NAME, pass, fail)
.with_react_perf_plugin(true)
.test_and_snapshot();

View file

@ -41,6 +41,9 @@ declare_oxc_lint!(
impl Rule for JsxNoNewFunctionAsProp {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if node.scope_id() == ctx.scopes().root_scope_id() {
return;
}
if let AstKind::JSXElement(jsx_elem) = node.kind() {
check_jsx_element(jsx_elem, ctx);
}
@ -106,22 +109,19 @@ fn test() {
use crate::tester::Tester;
let pass = vec![
r"<Item callback={this.props.callback} />",
r"<Item promise={new Promise()} />",
r"<Item onClick={bind(foo)} />",
r"<Item prop={0} />",
r"var a;<Item prop={a} />",
r"var a;a = 1;<Item prop={a} />",
r"var a;<Item prop={a} />",
r"const Foo = () => <Item callback={this.props.callback} />",
r"const Foo = () => (<Item promise={new Promise()} />)",
r"const Foo = () => (<Item onClick={bind(foo)} />)",
r"const Foo = () => (<Item prop={0} />)",
r"const Foo = () => { var a; return <Item prop={a} /> }",
r"const Foo = () => { var a;a = 1; return <Item prop={a} /> }",
r"const Foo = () => { var a;<Item prop={a} /> }",
r"function foo ({prop1 = function(){}, prop2}) {
return <Comp prop={prop2} />
}",
r"function foo ({prop1, prop2 = function(){}}) {
return <Comp prop={prop1} />
}",
];
let fail = vec![
r"<Item prop={function(){return true}} />",
r"<Item prop={() => true} />",
r"<Item prop={new Function('a', 'alert(a)')}/>",
@ -133,6 +133,18 @@ fn test() {
r"<Item prop={this.props.callback || (this.props.cb ? this.props.cb : function(){})} />",
];
let fail = vec![
r"const Foo = () => (<Item prop={function(){return true}} />)",
r"const Foo = () => (<Item prop={() => true} />)",
r"const Foo = () => (<Item prop={new Function('a', 'alert(a)')}/>)",
r"const Foo = () => (<Item prop={Function()}/>)",
r"const Foo = () => (<Item onClick={this.clickHandler.bind(this)} />)",
r"const Foo = () => (<Item callback={this.props.callback || function() {}} />)",
r"const Foo = () => (<Item callback={this.props.callback ? this.props.callback : function() {}} />)",
r"const Foo = () => (<Item prop={this.props.callback || this.props.callback ? this.props.callback : function(){}} />)",
r"const Foo = () => (<Item prop={this.props.callback || (this.props.cb ? this.props.cb : function(){})} />)",
];
Tester::new(JsxNoNewFunctionAsProp::NAME, pass, fail)
.with_react_perf_plugin(true)
.test_and_snapshot();

View file

@ -45,6 +45,9 @@ declare_oxc_lint!(
impl Rule for JsxNoNewObjectAsProp {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if node.scope_id() == ctx.scopes().root_scope_id() {
return;
}
if let AstKind::JSXElement(jsx_elem) = node.kind() {
check_jsx_element(jsx_elem, ctx);
}
@ -102,16 +105,20 @@ fn check_expression(expr: &Expression) -> Option<Span> {
fn test() {
use crate::tester::Tester;
let pass = vec![r"<Item config={staticConfig} />"];
let pass = vec![
r"<Item config={staticConfig} />",
r"<Item config={{}} />",
r"const Foo = () => <Item config={staticConfig} />",
];
let fail = vec![
r"<Item config={{}} />",
r"<Item config={new Object()} />",
r"<Item config={Object()} />",
r"<div style={{display: 'none'}} />",
r"<Item config={this.props.config || {}} />",
r"<Item config={this.props.config ? this.props.config : {}} />",
r"<Item config={this.props.config || (this.props.default ? this.props.default : {})} />",
r"const Foo = () => <Item config={{}} />",
r"const Foo = () => (<Item config={new Object()} />)",
r"const Foo = () => (<Item config={Object()} />)",
r"const Foo = () => (<div style={{display: 'none'}} />)",
r"const Foo = () => (<Item config={this.props.config || {}} />)",
r"const Foo = () => (<Item config={this.props.config ? this.props.config : {}} />)",
r"const Foo = () => (<Item config={this.props.config || (this.props.default ? this.props.default : {})} />)",
];
Tester::new(JsxNoNewObjectAsProp::NAME, pass, fail)

View file

@ -2,29 +2,29 @@
source: crates/oxc_linter/src/tester.rs
---
⚠ eslint-plugin-react-perf(jsx-no-jsx-as-prop): JSX attribute values should not contain other JSX.
╭─[jsx_no_jsx_as_prop.tsx:1:12]
1 │ <Item jsx={<SubItem />} />
· ───────────
╭─[jsx_no_jsx_as_prop.tsx:1:31]
1 │ const Foo = () => (<Item jsx={<SubItem />} />)
· ───────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-jsx-as-prop): JSX attribute values should not contain other JSX.
╭─[jsx_no_jsx_as_prop.tsx:1:30]
1 │ <Item jsx={this.props.jsx || <SubItem />} />
· ───────────
╭─[jsx_no_jsx_as_prop.tsx:1:49]
1 │ const Foo = () => (<Item jsx={this.props.jsx || <SubItem />} />)
· ───────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-jsx-as-prop): JSX attribute values should not contain other JSX.
╭─[jsx_no_jsx_as_prop.tsx:1:46]
1 │ <Item jsx={this.props.jsx ? this.props.jsx : <SubItem />} />
· ───────────
╭─[jsx_no_jsx_as_prop.tsx:1:65]
1 │ const Foo = () => (<Item jsx={this.props.jsx ? this.props.jsx : <SubItem />} />)
· ───────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-jsx-as-prop): JSX attribute values should not contain other JSX.
╭─[jsx_no_jsx_as_prop.tsx:1:77]
1 │ <Item jsx={this.props.jsx || (this.props.component ? this.props.component : <SubItem />)} />
· ───────────
╭─[jsx_no_jsx_as_prop.tsx:1:96]
1 │ const Foo = () => (<Item jsx={this.props.jsx || (this.props.component ? this.props.component : <SubItem />)} />)
· ───────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).

View file

@ -1,44 +1,44 @@
---
source: crates/oxc_linter/src/tester.rs
---
⚠ eslint-plugin-react-perf(jsx-no-new-array-as-prop): JSX attribute values should not contain Arrays created in the same scope.
╭─[jsx_no_new_array_as_prop.tsx:1:13]
1 │ <Item list={[]} />
· ──
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-array-as-prop): JSX attribute values should not contain Arrays created in the same scope.
╭─[jsx_no_new_array_as_prop.tsx:1:13]
1 │ <Item list={new Array()} />
· ───────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-array-as-prop): JSX attribute values should not contain Arrays created in the same scope.
╭─[jsx_no_new_array_as_prop.tsx:1:13]
1 │ <Item list={Array()} />
· ───────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-array-as-prop): JSX attribute values should not contain Arrays created in the same scope.
╭─[jsx_no_new_array_as_prop.tsx:1:32]
1 │ <Item list={this.props.list || []} />
1 │ const Foo = () => (<Item list={[]} />)
· ──
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-array-as-prop): JSX attribute values should not contain Arrays created in the same scope.
╭─[jsx_no_new_array_as_prop.tsx:1:49]
1 │ <Item list={this.props.list ? this.props.list : []} />
· ──
╭─[jsx_no_new_array_as_prop.tsx:1:32]
1 │ const Foo = () => (<Item list={new Array()} />)
· ───────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-array-as-prop): JSX attribute values should not contain Arrays created in the same scope.
╭─[jsx_no_new_array_as_prop.tsx:1:67]
1 │ <Item list={this.props.list || (this.props.arr ? this.props.arr : [])} />
· ──
╭─[jsx_no_new_array_as_prop.tsx:1:32]
1 │ const Foo = () => (<Item list={Array()} />)
· ───────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-array-as-prop): JSX attribute values should not contain Arrays created in the same scope.
╭─[jsx_no_new_array_as_prop.tsx:1:51]
1 │ const Foo = () => (<Item list={this.props.list || []} />)
· ──
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-array-as-prop): JSX attribute values should not contain Arrays created in the same scope.
╭─[jsx_no_new_array_as_prop.tsx:1:68]
1 │ const Foo = () => (<Item list={this.props.list ? this.props.list : []} />)
· ──
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-array-as-prop): JSX attribute values should not contain Arrays created in the same scope.
╭─[jsx_no_new_array_as_prop.tsx:1:86]
1 │ const Foo = () => (<Item list={this.props.list || (this.props.arr ? this.props.arr : [])} />)
· ──
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).

View file

@ -2,64 +2,64 @@
source: crates/oxc_linter/src/tester.rs
---
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:13]
1 │ <Item prop={function(){return true}} />
· ───────────────────────
╭─[jsx_no_new_function_as_prop.tsx:1:32]
1 │ const Foo = () => (<Item prop={function(){return true}} />)
· ───────────────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:13]
1 │ <Item prop={() => true} />
· ──────────
╭─[jsx_no_new_function_as_prop.tsx:1:32]
1 │ const Foo = () => (<Item prop={() => true} />)
· ──────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:13]
1 │ <Item prop={new Function('a', 'alert(a)')}/>
· ─────────────────────────────
╭─[jsx_no_new_function_as_prop.tsx:1:32]
1 │ const Foo = () => (<Item prop={new Function('a', 'alert(a)')}/>)
· ─────────────────────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:13]
1 │ <Item prop={Function()}/>
· ──────────
╭─[jsx_no_new_function_as_prop.tsx:1:32]
1 │ const Foo = () => (<Item prop={Function()}/>)
· ──────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:16]
1 │ <Item onClick={this.clickHandler.bind(this)} />
· ────────────────────────────
╭─[jsx_no_new_function_as_prop.tsx:1:35]
1 │ const Foo = () => (<Item onClick={this.clickHandler.bind(this)} />)
· ────────────────────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:40]
1 │ <Item callback={this.props.callback || function() {}} />
· ─────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:61]
1 │ <Item callback={this.props.callback ? this.props.callback : function() {}} />
· ─────────────
╭─[jsx_no_new_function_as_prop.tsx:1:59]
1 │ const Foo = () => (<Item callback={this.props.callback || function() {}} />)
· ─────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:80]
1 │ <Item prop={this.props.callback || this.props.callback ? this.props.callback : function(){}} />
· ────────────
1 │ const Foo = () => (<Item callback={this.props.callback ? this.props.callback : function() {}} />)
· ─────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:69]
1 │ <Item prop={this.props.callback || (this.props.cb ? this.props.cb : function(){})} />
· ────────────
╭─[jsx_no_new_function_as_prop.tsx:1:99]
1 │ const Foo = () => (<Item prop={this.props.callback || this.props.callback ? this.props.callback : function(){}} />)
· ────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-function-as-prop): JSX attribute values should not contain functions created in the same scope.
╭─[jsx_no_new_function_as_prop.tsx:1:88]
1 │ const Foo = () => (<Item prop={this.props.callback || (this.props.cb ? this.props.cb : function(){})} />)
· ────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).

View file

@ -2,50 +2,50 @@
source: crates/oxc_linter/src/tester.rs
---
⚠ eslint-plugin-react-perf(jsx-no-new-object-as-prop): JSX attribute values should not contain objects created in the same scope.
╭─[jsx_no_new_object_as_prop.tsx:1:15]
1 │ <Item config={{}} />
· ──
╭─[jsx_no_new_object_as_prop.tsx:1:33]
1 │ const Foo = () => <Item config={{}} />
· ──
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-object-as-prop): JSX attribute values should not contain objects created in the same scope.
╭─[jsx_no_new_object_as_prop.tsx:1:15]
1 │ <Item config={new Object()} />
· ────────────
╭─[jsx_no_new_object_as_prop.tsx:1:34]
1 │ const Foo = () => (<Item config={new Object()} />)
· ────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-object-as-prop): JSX attribute values should not contain objects created in the same scope.
╭─[jsx_no_new_object_as_prop.tsx:1:15]
1 │ <Item config={Object()} />
· ────────
╭─[jsx_no_new_object_as_prop.tsx:1:34]
1 │ const Foo = () => (<Item config={Object()} />)
· ────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-object-as-prop): JSX attribute values should not contain objects created in the same scope.
╭─[jsx_no_new_object_as_prop.tsx:1:13]
1 │ <div style={{display: 'none'}} />
· ─────────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-object-as-prop): JSX attribute values should not contain objects created in the same scope.
╭─[jsx_no_new_object_as_prop.tsx:1:36]
1 │ <Item config={this.props.config || {}} />
· ──
╭─[jsx_no_new_object_as_prop.tsx:1:32]
1 │ const Foo = () => (<div style={{display: 'none'}} />)
· ─────────────────
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-object-as-prop): JSX attribute values should not contain objects created in the same scope.
╭─[jsx_no_new_object_as_prop.tsx:1:55]
1 │ <Item config={this.props.config ? this.props.config : {}} />
1 │ const Foo = () => (<Item config={this.props.config || {}} />)
· ──
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-object-as-prop): JSX attribute values should not contain objects created in the same scope.
╭─[jsx_no_new_object_as_prop.tsx:1:79]
1 │ <Item config={this.props.config || (this.props.default ? this.props.default : {})} />
· ──
╭─[jsx_no_new_object_as_prop.tsx:1:74]
1 │ const Foo = () => (<Item config={this.props.config ? this.props.config : {}} />)
· ──
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).
⚠ eslint-plugin-react-perf(jsx-no-new-object-as-prop): JSX attribute values should not contain objects created in the same scope.
╭─[jsx_no_new_object_as_prop.tsx:1:98]
1 │ const Foo = () => (<Item config={this.props.config || (this.props.default ? this.props.default : {})} />)
· ──
╰────
help: simplify props or memoize props in the parent component (https://react.dev/reference/react/memo#my-component-rerenders-when-a-prop-is-an-object-or-array).

View file

@ -32,6 +32,8 @@ pub struct ScopeTree {
}
impl ScopeTree {
const ROOT_SCOPE_ID: ScopeId = ScopeId::from_usize_unchecked(0);
pub fn len(&self) -> usize {
self.parent_ids.len()
}
@ -80,8 +82,8 @@ impl ScopeTree {
}
#[inline]
pub fn root_scope_id(&self) -> ScopeId {
ScopeId::new(0)
pub const fn root_scope_id(&self) -> ScopeId {
Self::ROOT_SCOPE_ID
}
pub fn root_flags(&self) -> ScopeFlags {