diff --git a/its/ruling/src/test/expected/ts/console/typescript-S6763.json b/its/ruling/src/test/expected/ts/console/typescript-S6763.json new file mode 100644 index 0000000000..b60fbb517a --- /dev/null +++ b/its/ruling/src/test/expected/ts/console/typescript-S6763.json @@ -0,0 +1,14 @@ +{ +"console:src/components/ProjectSelection/ProjectSelection.tsx": [ +160 +], +"console:src/views/ProjectRootView/ProjectRootView.tsx": [ +64 +], +"console:src/views/ProjectRootView/SideNav.tsx": [ +147 +], +"console:src/views/models/DatabrowserView/DatabrowserView.tsx": [ +134 +] +} diff --git a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java index f05491ed12..baa3e40686 100644 --- a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java +++ b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java @@ -283,6 +283,7 @@ public static List> getAllChecks() { NoProtoCheck.class, NoRedundantJumpCheck.class, NoRedundantOptionalCheck.class, + NoRedundantShouldComponentUpdateCheck.class, NoRedundantTypeConstituentsCheck.class, NoReferrerPolicyCheck.class, NoRegexSpacesCheck.class, diff --git a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoRedundantShouldComponentUpdateCheck.java b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoRedundantShouldComponentUpdateCheck.java new file mode 100644 index 0000000000..3313f7cff9 --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoRedundantShouldComponentUpdateCheck.java @@ -0,0 +1,36 @@ +/** + * SonarQube JavaScript Plugin + * Copyright (C) 2011-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.javascript.checks; + +import org.sonar.check.Rule; +import org.sonar.plugins.javascript.api.EslintBasedCheck; +import org.sonar.plugins.javascript.api.JavaScriptRule; +import org.sonar.plugins.javascript.api.TypeScriptRule; + +@JavaScriptRule +@TypeScriptRule +@Rule(key = "S6763") +public class NoRedundantShouldComponentUpdateCheck implements EslintBasedCheck { + + @Override + public String eslintKey() { + return "no-redundant-should-component-update"; + } +} diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6763.html b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6763.html new file mode 100644 index 0000000000..f221ecab43 --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6763.html @@ -0,0 +1,41 @@ +

Why is this an issue?

+

In React, a PureComponent is a class component that is optimized for performance by implementing a shallow comparison of props and +state. It is a subclass of the regular React Component class and provides a default implementation of the +shouldComponentUpdate method.

+

The shouldComponentUpdate method is responsible for determining whether a component should re-render or not. By default, it returns +true and triggers a re-render every time the component receives new props or state. However, PureComponent overrides this method and +performs a shallow comparison of the current and next props and state. If there are no changes, it prevents unnecessary re-renders by returning +false.

+

Therefore, defining a shouldComponentUpdate method while extending PureComponent is redundant and should be avoided. By +not defining shouldComponentUpdate, you allow React.PureComponent to handle the optimization for you.

+
+class MyComponent extends React.PureComponent { // Noncompliant
+  shouldComponentUpdate() {
+    // does something
+  }
+
+  render() {
+    return <div>Hello!</div>
+  }
+}
+
+

You should either remove the redundant method shouldComponentUpdate or turn your component into a regular one by extending +Component.

+
+class MyComponent extends React.Component {
+  shouldComponentUpdate() {
+    // does something
+  }
+
+  render() {
+    return <div>Hello!</div>
+  }
+}
+
+

Resources

+

Documentation

+ + diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6763.json b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6763.json new file mode 100644 index 0000000000..2e74b301d1 --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6763.json @@ -0,0 +1,29 @@ +{ + "title": "\"shouldComponentUpdate\" should not be defined when extending \"React.PureComponent\"", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "react" + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-6763", + "sqKey": "S6763", + "scope": "All", + "quickfix": "infeasible", + "code": { + "impacts": { + "MAINTAINABILITY": "HIGH", + "RELIABILITY": "MEDIUM", + "SECURITY": "LOW" + }, + "attribute": "CONVENTIONAL" + }, + "compatibleLanguages": [ + "JAVASCRIPT", + "TYPESCRIPT" + ] +} diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json index 28b7f81954..1eda93927f 100644 --- a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json @@ -282,6 +282,7 @@ "S6754", "S6756", "S6757", - "S6759" + "S6759", + "S6763" ] }