feat: add react/no-redundant-should-component-update lint rule
MODIFY
packages/@romejs/diagnostics/categories.ts
packages/@romejs/diagnostics/categories.ts
@@ -165,6 +165,7 @@ type LintDiagnosticCategory =
| "lint/react/noDidMountSetState"
| "lint/react/noDidUpdateSetState"
| "lint/react/noFindDOMNode"
+ | "lint/react/noRedundantShouldComponentUpdate"
| "lint/react/noUnsafe"
| "lint/react/noWillUpdateSetState"
| "lint/react/reactInJsxScope"

MODIFY
packages/@romejs/diagnostics/descriptions.ts
packages/@romejs/diagnostics/descriptions.ts
@@ -292,6 +292,10 @@ export const descriptions = createMessages({
},
// @romejs/js-compiler
LINT: {
+ REACT_NO_REDUNDANT_SHOULD_COMPONENT_UPDATE: {
+ category: "lint/react/noRedundantShouldComponentUpdate",
+ message: "Do not implement <emphasis>shouldComponentUpdate</emphasis> when extending <emphasis>React.PureComponent</emphasis>.",
+ },
REACT_NO_UNSAFE: (oldMethod: string, newMethod: string, details: string) => ({
category: "lint/react/noUnsafe",
message: `<emphasis>${oldMethod}</emphasis> is unsafe for use in async rendering. Update the component to use ${newMethod} instead. ${details}`,

MODIFY
packages/@romejs/js-compiler/lint/rules/index.ts
packages/@romejs/js-compiler/lint/rules/index.ts
@@ -79,6 +79,7 @@ import noDangerWithChildren from "./react/noDangerWithChildren";
import noDidMountSetState from "./react/noDidMountSetState";
import noDidUpdateSetState from "./react/noDidUpdateSetState";
import noFindDOMNode from "./react/noFindDOMNode";
+import noRedundantShouldComponentUpdate from "./react/noRedundantShouldComponentUpdate";
import noUnsafe from "./react/noUnsafe";
import noWillUpdateSetState from "./react/noWillUpdateSetState";
import reactInJsxScope from "./react/reactInJsxScope";
@@ -160,6 +161,7 @@ export const lintTransforms = [
noDidMountSetState,
noDidUpdateSetState,
noFindDOMNode,
+ noRedundantShouldComponentUpdate,
noUnsafe,
noWillUpdateSetState,
reactInJsxScope,

ADD
packages/@romejs/js-compiler/lint/rules/react/noRedundantShouldComponentUpdate.test.ts
+import {test} from "rome";
+import {testLintMultiple} from "../testHelpers";
+
+test(
+ "no redundant should component update",
+ async (t) => {
+ await testLintMultiple(
+ t,
+ [
+ // INVALID
+ `
+ class Hello extends React.PureComponent {
+ componentShouldUpdate() {}
+ }
+ `,
+ `
+ class Hello extends PureComponent {
+ componentShouldUpdate() {}
+ }
+ `,
+ // VALID
+ `
+ class Hello extends React.PureComponent {
+ componentDidMount() {}
+ }
+ `,
+ `
+ class Hello extends PureComponent {
+ componentDidMount() {}
+ }
+ `,
+ ],
+ {category: "lint/react/noRedundantShouldComponentUpdate"},
+ );
+ },
+);

ADD
packages/@romejs/js-compiler/lint/rules/react/noRedundantShouldComponentUpdate.ts
+import {Path, TransformExitResult} from "@romejs/js-compiler";
+import {descriptions} from "@romejs/diagnostics";
+import {doesNodeMatchPattern} from "@romejs/js-ast-utils";
+
+export default {
+ name: "noRedundantShouldComponentUpdate",
+ enter(path: Path): TransformExitResult {
+ const {node} = path;
+
+ if (
+ node.type === "JSClassDeclaration" &&
+ !!node.meta.body.find((member) =>
+ member.type === "JSClassMethod" &&
+ member.key.type === "JSStaticPropertyKey" &&
+ member.key.value.type === "JSIdentifier" &&
+ member.key.value.name === "componentShouldUpdate"
+ ) &&
+ (doesNodeMatchPattern(node.meta.superClass, "React.PureComponent") ||
+ doesNodeMatchPattern(node.meta.superClass, "PureComponent"))
+ ) {
+ path.context.addNodeDiagnostic(
+ node,
+ descriptions.LINT.REACT_NO_REDUNDANT_SHOULD_COMPONENT_UPDATE,
+ );
+ }
+
+ return node;
+ },
+};

feat: add react/no-redundant-should-component-update lint rule (#490)

Co-authored-by: Sebastian <853712+sebmck@users.noreply.github.com>