-
-
Notifications
You must be signed in to change notification settings - Fork 763
feat(linter): add react/require-optimization rule
#17370
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| /// ``` | ||
| RequireOptimization, | ||
| react, | ||
| perf, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure should this be style or perf?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds the react/require-optimization linter rule that enforces React class components to have a shouldComponentUpdate method or use optimization alternatives like PureComponent or decorators/mixins. The rule helps identify components that may cause unnecessary re-renders and performance issues.
Key Changes
- Implements detection of React class components (ES6 and ES5 via
createReactClass) - Validates presence of
shouldComponentUpdatemethod - Supports
allowDecoratorsconfiguration option for custom optimization decorators/mixins - Includes comprehensive test coverage for various component patterns
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
crates/oxc_linter/src/rules/react/require_optimization.rs |
Main implementation of the rule with component detection, SCU validation, and decorator/mixin support |
crates/oxc_linter/src/snapshots/react_require_optimization.snap |
Snapshot tests showing diagnostic output for various non-optimized component patterns |
crates/oxc_linter/src/rules.rs |
Registers the new rule module in the linter's rule collection |
crates/oxc_linter/src/generated/rule_runner_impls.rs |
Generated code specifying which AST node types trigger the rule (CallExpression and Class) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// checks if class is React.Component | ||
| fn is_react_class_component(node: &AstNode) -> bool { | ||
| let AstKind::Class(class_expr) = node.kind() else { | ||
| return false; | ||
| }; | ||
| if let Some(super_class) = &class_expr.super_class { | ||
| if let Some(member_expr) = super_class.as_member_expression() | ||
| && let Expression::Identifier(ident) = member_expr.object() | ||
| { | ||
| return ident.name == "React" | ||
| && member_expr.static_property_name().is_some_and(|name| name == "Component"); | ||
| } | ||
|
|
||
| if let Some(ident_reference) = super_class.get_identifier_reference() { | ||
| return ident_reference.name == "Component"; | ||
| } | ||
| } | ||
|
|
||
| false | ||
| } |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function is_react_class_component only checks if a class extends React.Component or Component, but it doesn't exclude classes that extend React.PureComponent or PureComponent. Since PureComponent already implements shouldComponentUpdate with shallow prop comparison, these classes should not be flagged by this rule. The test cases on lines 358-370 expect PureComponent classes to pass, but this implementation would incorrectly flag them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont think thats right, PureComponent automatically implements shouldComponentUpdate and this function will just skip it
| #[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)] | ||
| #[schemars(rename_all = "camelCase")] | ||
| pub struct RequireOptimizationConfig { | ||
| /// Sets the allowed names of decorators. If the variable is present in the chain of decorators, it validates |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation comment is incomplete. It says "If the variable is present in the chain of decorators, it validates" but doesn't complete the thought about what it validates or what happens. This should be completed to provide a clear explanation, for example: "If the variable is present in the chain of decorators, the component is considered optimized."
| /// Sets the allowed names of decorators. If the variable is present in the chain of decorators, it validates | |
| /// Sets the allowed names of decorators. If the variable is present in the chain of decorators, the component is | |
| /// considered optimized and satisfies this rule. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
| OxcDiagnostic::warn("Component is not optimized. Please add a shouldComponentUpdate method.") | ||
| .with_label(span) |
Copilot
AI
Dec 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message only mentions adding a shouldComponentUpdate method, but doesn't mention the alternative of using PureComponent or React.memo. While the documentation in the "Why is this bad?" section mentions these alternatives, the diagnostic message should also reference them to provide more complete guidance. Consider updating the message to something like: "Component is not optimized. Please add a shouldComponentUpdate method, extend PureComponent, or use React.memo."
| OxcDiagnostic::warn("Component is not optimized. Please add a shouldComponentUpdate method.") | |
| .with_label(span) | |
| OxcDiagnostic::warn( | |
| "Component is not optimized. Please add a shouldComponentUpdate method, extend PureComponent, or use React.memo.", | |
| ) | |
| .with_label(span) |
CodSpeed Performance ReportMerging #17370 will not alter performanceComparing Summary
Footnotes
|
beda0e7 to
c2b7f7f
Compare
connorshea
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few notes for the docs
| declare_oxc_lint!( | ||
| /// ### What it does | ||
| /// | ||
| /// Enforce React components to have a shouldComponentUpdate method |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should note that this only applies to class components, since most components in modern react are function-based at this point. Also, based on the react docs I think we should probably have a note in the docs here that this rule isn't encouraged. React is able to optimize this itself in many many cases and having devs implement this themselves is a lot more error-prone. At least, in my opinion.
https://react.dev/reference/react/Component#shouldcomponentupdate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added note about class components
|
This rule should also have a should_run that checks if it's a jsx file, no need to run on non-jsx/tsx files. |
fixed |
this PR adds
react/require-optimizationrule, issue #1022source doc
source code