Skip to content

Conversation

@baevm
Copy link
Contributor

@baevm baevm commented Dec 26, 2025

this PR adds react/require-optimization rule, issue #1022

source doc
source code

Copilot AI review requested due to automatic review settings December 26, 2025 14:13
@baevm baevm requested a review from camc314 as a code owner December 26, 2025 14:13
@github-actions github-actions bot added A-linter Area - Linter C-enhancement Category - New feature or request labels Dec 26, 2025
/// ```
RequireOptimization,
react,
perf,
Copy link
Contributor Author

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?

Copy link
Contributor

Copilot AI left a 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 shouldComponentUpdate method
  • Supports allowDecorators configuration 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.

Comment on lines +238 to +258
/// 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
}
Copy link

Copilot AI Dec 26, 2025

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.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

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
Copy link

Copilot AI Dec 26, 2025

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."

Suggested change
/// 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.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment on lines +19 to +20
OxcDiagnostic::warn("Component is not optimized. Please add a shouldComponentUpdate method.")
.with_label(span)
Copy link

Copilot AI Dec 26, 2025

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."

Suggested change
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)

Copilot uses AI. Check for mistakes.
@codspeed-hq
Copy link

codspeed-hq bot commented Dec 26, 2025

CodSpeed Performance Report

Merging #17370 will not alter performance

Comparing baevm:react/require-optimization (76206c4) with main (d2abc78)

Summary

✅ 4 untouched
⏩ 41 skipped1

Footnotes

  1. 41 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@baevm baevm force-pushed the react/require-optimization branch from beda0e7 to c2b7f7f Compare December 26, 2025 14:38
Copy link
Contributor

@connorshea connorshea left a 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
Copy link
Contributor

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

Copy link
Contributor Author

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

@connorshea
Copy link
Contributor

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.

@baevm
Copy link
Contributor Author

baevm commented Dec 26, 2025

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

@camc314 camc314 self-assigned this Dec 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-linter Area - Linter C-enhancement Category - New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants