Repository: jsx-eslint/eslint-plugin-react (JavaScript)

Issue:
False-positive for react/display-name after 7.29.4 → 7.30.0 upgrade
After upgrading eslint-plugin-react from 7.29.4 to 7.30.0 a new linting error appeared in my project that doesn't seem right. My project is a big full-stack monolith web app and it contains both Vue.js and React.js code. Now I am getting `react/display-name` for some Vue/Vuex code that has nothing to do with React. I stripped down the file, the original was much longer, but this still triggers the error:

```js
import Vuex from 'vuex'
import Vue from 'vue'

// code omitted

const getters = {
  getChat: state => (scopePath, partnerId) => {
    const selectedChatScope = state.chats && state.chats.find(chat => chat.path === scopePath)

    if (!selectedChatScope) {
      return null
    }

    return 'something'
  }
}

export {
  getters
}
```

```
  7:21  error  Component definition is missing display name  react/display-name
```


Discussion:
cc @golopot 



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dfa0a6f6b4..4491394d8a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
 * [`require-default-props`]: avoid a crash when function has no props param ([#3350][] @noahnu)
 * [`display-name`], component detection: fix HOF returning null as Components ([#3347][] @jxm-math)
 * [`forbid-prop-types`]: Ignore objects that are not of type React.PropTypes ([#3326][] @TildaDares)
+* [`display-name`], component detection: fix false positive for HOF returning only nulls and literals ([#3305][] @golopot)
 
 ### Changed
 * [Refactor] [`jsx-indent-props`]: improved readability of the checkNodesIndent function ([#3315][] @caroline223)
@@ -49,6 +50,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
 [#3315]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3315
 [#3314]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3314
 [#3311]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3311
+[#3305]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3305
 [#3262]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3262
 
 ## [7.30.1] - 2022.06.23
diff --git a/lib/util/Components.js b/lib/util/Components.js
index 7abfbee72f..273e424283 100644
--- a/lib/util/Components.js
+++ b/lib/util/Components.js
@@ -503,7 +503,6 @@ function componentRule(rule, context) {
         if (
           (node.parent.type === 'ReturnStatement' || (node.parent.type === 'ArrowFunctionExpression' && node.parent.expression))
           && !utils.isReturningJSX(node)
-          && !utils.isReturningOnlyNull(node)
         ) {
           return undefined;
         }


Test patch:
diff --git a/tests/lib/rules/display-name.js b/tests/lib/rules/display-name.js
index 841af839fc..420bc47c7b 100644
--- a/tests/lib/rules/display-name.js
+++ b/tests/lib/rules/display-name.js
@@ -556,6 +556,17 @@ ruleTester.run('display-name', rule, {
         }
       `,
     },
+    {
+      // issue #3300
+      code: `
+        const f = (a) => () => {
+          if (a) {
+            return null;
+          }
+          return 1;
+        };
+      `,
+    },
     {
       code: `
         class Test {
@@ -1169,33 +1180,5 @@ ruleTester.run('display-name', rule, {
         },
       ],
     },
-    {
-      code: `
-        Demo = () => () => null;
-      `,
-      errors: [{ messageId: 'noDisplayName' }],
-    },
-    {
-      code: `
-        demo = {
-          Property: () => () => null
-        }
-      `,
-      errors: [{ messageId: 'noDisplayName' }],
-    },
-    {
-      code: `
-        Demo = function() {return function() {return null;};};
-      `,
-      errors: [{ messageId: 'noDisplayName' }],
-    },
-    {
-      code: `
-        demo = {
-          Property: function() {return function() {return null;};}
-        }
-      `,
-      errors: [{ messageId: 'noDisplayName' }],
-    },
   ]),
 });
diff --git a/tests/lib/rules/no-this-in-sfc.js b/tests/lib/rules/no-this-in-sfc.js
index a8e80b8b45..0bbf84af28 100644
--- a/tests/lib/rules/no-this-in-sfc.js
+++ b/tests/lib/rules/no-this-in-sfc.js
@@ -275,58 +275,5 @@ ruleTester.run('no-this-in-sfc', rule, {
         { messageId: 'noThisInSFC' },
       ],
     },
-    {
-      code: `
-        class Foo {
-          bar() {
-            return () => {
-              this.something();
-              return null;
-            }
-          }
-        }
-      `,
-      errors: [{ messageId: 'noThisInSFC' }],
-    },
-    {
-      code: `
-        class Foo {
-          bar = () => () => {
-            this.something();
-            return null;
-          };
-        }
-      `,
-      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove `no-ts-old` and fix
-      errors: [{ messageId: 'noThisInSFC' }],
-    },
-    {
-      code: `
-        class Foo {
-          bar() {
-            function Bar(){
-              return () => {
-                this.something();
-                return null;
-              }
-            }
-          }
-        }
-      `,
-      errors: [{ messageId: 'noThisInSFC' }],
-    },
-    {
-      code: `
-        class Foo {
-          bar() {
-            () => () => {
-              this.something();
-              return null;
-            };
-          }
-        }
-      `,
-      errors: [{ messageId: 'noThisInSFC' }],
-    },
   ]),
 });