feat(eslint-config)!: default react-perf and jsx-props-no-spreading off - #1120
Conversation
The 29.0.1 release repointed lint-staged-config's manifest without regenerating pnpm-lock.yaml, which still records 29.0.0, so every job on main dies at `pnpm install --frozen-lockfile`. This also deadlocks the release pipeline. `Semantic Release` starts with a "Wait for tests to succeed" gate, the tests cannot pass while the lockfile is stale, and the lockfile is only refreshed from inside that same job — so the pipeline cannot repair itself and stays blocked until a lockfile lands by hand. This is the second occurrence today; 29.0.0 needed the same fix in #1118. Regenerate. Verified with the same frozen install CI runs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FP75FgnREe4L45kZtsa9a
The react-perf rules predate the React Compiler, which memoises component output automatically. Satisfying them means hand-rolling useMemo/useCallback, and manual memoisation can make the compiler bail on a component rather than optimise it, so following the rule can measurably reduce optimisation. They also fire on every prop object of animation libraries, where object props are the API rather than an accident. A reported app saw 211 of 1027 problems from these two rules alone, essentially all library props and none a genuine performance finding. `react/jsx-props-no-spreading` fights the standard composition pattern for Radix/shadcn-style primitives, where a wrapper forwards the underlying element's whole prop surface. Complying means enumerating every prop of every primitive by hand and redoing it whenever the upstream library changes. The react-perf disables sit after the plugin's recommended spread, which would otherwise re-enable them. The storybook-scoped `jsx-props-no-spreading` off-block is removed as dead: the rule is now off everywhere, and a consumer re-enabling it would be appended after that block and win regardless. `react-x/no-unstable-context-value` and `react/jsx-no-constructed-context-values` stay enabled. The compiler does not memoise across a context provider boundary, so an unstable value there still re-renders every consumer; those two flag a real effect rather than a referential-equality technicality. BREAKING CHANGE: `react-perf/jsx-no-new-object-as-prop`, `react-perf/jsx-no-new-array-as-prop`, `react-perf/jsx-no-new-function-as-prop`, `react-perf/jsx-no-jsx-as-prop` and `react/jsx-props-no-spreading` no longer report by default. Projects that want them must enable them in their own config. Closes #1085 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FP75FgnREe4L45kZtsa9a
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Thank you for following the naming conventions! 🙏 |
|
Warning Review limit reached
Next review available in: 28 seconds Limit details: You’ve used all 1 included review currently available under your plan. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
commit: |
Closes #1085.
Verified both claims against
mainbefore changing anything:react/jsx-props-no-spreadingiserrorin the main React rules block, disabled only for Storybook files.react-perf/jsx-no-new-object-as-prop,jsx-no-new-array-as-propandjsx-no-new-function-as-propcome in aterrorvia the plugin's spreadrecommendedconfig.Change
react-perf/jsx-no-new-object-as-propreact-perf/jsx-no-new-array-as-propreact-perf/jsx-no-new-function-as-propreact-perf/jsx-no-jsx-as-propreact/jsx-props-no-spreadingThe reasoning in the issue holds up. The react-perf rules predate the React Compiler, and satisfying them via manual memoisation can make the compiler bail on a component rather than optimise it — so the rule can work against the thing it is trying to achieve. They also fire on every prop object of animation libraries, where object props are the API.
jsx-props-no-spreadingfights the standard Radix/shadcn composition pattern, where a wrapper forwards the underlying element's whole prop surface.Ordering matters here
The react-perf disables must sit after
...configRules(pluginReactPerformance.configs?.flat?.recommended)in the same rules object. My first attempt put them earlier and the spread silently re-enabled all three — the probe still reported every violation. Worth knowing if these are ever moved.The Storybook-scoped
jsx-props-no-spreadingoff-block is removed as dead: the rule is off everywhere now, and a consumer re-enabling it would be appended after that block and win regardless.What I did not turn off
The issue asks whether
react-x/no-unstable-context-valueandreact/jsx-no-constructed-context-valuesbelong in the same group. I have left both aterror.They are not the same case. The compiler does not memoise across a context provider boundary, so an unstable provider value still re-renders every consumer of that context no matter what the compiler does to the component. Those two flag a real effect, where the react-perf rules flag a referential-equality technicality the compiler now handles. Happy to revisit with a concrete example if you are seeing false positives.
Verification
Probed with a component using Motion-style
animate/initial/transitionprops and a Radix-style primitive forwarding{...properties}:react-perfviolations on the props--print-configresolves all five rules to0while the two context rules stay at2Then build 8/8, lint 6/6, tests 4/4 projects.
Breaking
These rules no longer report by default. Projects that want them must enable them in their own config.
🤖 Generated with Claude Code
https://claude.ai/code/session_014FP75FgnREe4L45kZtsa9a