add noWillUpdateSetState rule and tests
MODIFY
packages/@romejs/diagnostics/categories.ts
packages/@romejs/diagnostics/categories.ts
@@ -148,6 +148,7 @@ type LintDiagnosticCategory =
| "lint/noTemplateCurlyInString"
| "lint/noUnsafeFinally"
| "lint/noVar"
+ | "lint/noWillUpdateSetState"
| "lint/preferBlockStatements"
| "lint/preferFunctionDeclarations"
| "lint/preferTemplate"

MODIFY
packages/@romejs/diagnostics/descriptions.ts
packages/@romejs/diagnostics/descriptions.ts
@@ -292,6 +292,10 @@ export const descriptions = createMessages({
},
// @romejs/js-compiler
LINT: {
+ NO_WILL_UPDATE_SET_STATE: {
+ category: "lint/noWillUpdateSetState",
+ message: "Avoid this.setState in componentWillUpdate",
+ },
NO_DID_UPDATE_SET_STATE: {
category: "lint/noDidUpdateSetState",
message: "Avoid this.setState in componentDidUpdate",

MODIFY
packages/@romejs/js-compiler/lint/rules/index.ts
packages/@romejs/js-compiler/lint/rules/index.ts
@@ -62,6 +62,7 @@ import noShorthandArrayType from "./regular/noShorthandArrayType";
import noTemplateCurlyInString from "./regular/noTemplateCurlyInString";
import noUnsafeFinally from "./regular/noUnsafeFinally";
import noVar from "./regular/noVar";
+import noWillUpdateSetState from "./react/noWillUpdateSetState";
import preferBlockStatements from "./regular/preferBlockStatements";
import preferFunctionDeclarations from "./regular/preferFunctionDeclarations";
import preferTemplate from "./regular/preferTemplate";
@@ -134,6 +135,7 @@ export const lintTransforms = [
noTemplateCurlyInString,
noUnsafeFinally,
noVar,
+ noWillUpdateSetState,
preferBlockStatements,
preferFunctionDeclarations,
preferTemplate,

ADD
packages/@romejs/js-compiler/lint/rules/react/noWillUpdateSetState.test.ts
+import {test} from "rome";
+import {testLintMultiple} from "../testHelpers";
+
+test(
+ "no this.setState in componentWillUpdate",
+ async (t) => {
+ await testLintMultiple(
+ t,
+ [
+ // INVALID
+ `
+ class Hello extends React.Component {
+ componentWillUpdate() {
+ this.setState({
+ name: 'John'
+ });
+ }
+ }
+ `,
+ `
+ class Hello extends React.Component {
+ componentWillUpdate() {
+ foo();
+ this.setState({
+ name: 'John'
+ });
+ }
+ }
+ `,
+ `
+ class Hello extends Component {
+ UNSAFE_componentWillUpdate() {
+ foo();
+ this.setState({
+ name: 'John'
+ });
+ }
+ }
+ `,
+ // VALID
+ `
+ class Hello extends React.Component {
+ componentWillUpdate() {
+ foo()
+ }
+ }
+ `,
+ `
+ class Hello extends React.Component {
+ UNSAFE_componentWillUpdate() {
+ foo()
+ }
+ }
+ `,
+ ],
+ {category: "lint/noWillUpdateSetState"},
+ );
+ },
+);

ADD
packages/@romejs/js-compiler/lint/rules/react/noWillUpdateSetState.ts
+import {Path, TransformExitResult} from "@romejs/js-compiler";
+import {descriptions} from "@romejs/diagnostics";
+import {doesNodeMatchPattern} from "@romejs/js-ast-utils";
+
+function inComponentWillUpdate(path: Path): boolean {
+ return (
+ path.findAncestry(({node}) =>
+ node.type === "ClassMethod" &&
+ node.key.type === "StaticPropertyKey" &&
+ node.key.value.type === "Identifier" &&
+ (node.key.value.name === "componentWillUpdate" ||
+ node.key.value.name === "UNSAFE_componentWillUpdate")
+ ) !== undefined
+ );
+}
+
+export default {
+ name: "noWillUpdateSetState",
+ enter(path: Path): TransformExitResult {
+ const {node} = path;
+
+ if (
+ doesNodeMatchPattern(node, "this.setState") &&
+ inComponentWillUpdate(path)
+ ) {
+ path.context.addNodeDiagnostic(
+ node,
+ descriptions.LINT.NO_WILL_UPDATE_SET_STATE,
+ );
+ }
+
+ return node;
+ },
+};

add noWillUpdateSetState rule and tests