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

Issue:
False positive for react/display-name on function value assignment to identifier starting with `_`
Both this codes are wrongly identified as Components:

```javascript
obj._property = (a) => {
  if (a == null) return null;
  return f(a);
};
```
```javascript
_variable = (a) => {
  if (a == null) return null;
  return f(a);
};
```
Apparently because words starting with `_` are claimed as starting with a capital letter.

Pull request description:
[Fix] display-name: fix identifying `_` as a capital letter
Fix #3334

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8743fa5e..90bc4e80 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
 * [`jsx-key`]: avoid a crash from optional chaining from [#3320][] ([#3327][] @ljharb)
 * [`jsx-key`]: avoid a crash on a non-array node.body from [#3320][] ([#3328][] @ljharb)
 * [`display-name`]: fix false positive for assignment of function returning null ([#3331][] @apbarrero)
+* [`display-name`]: fix identifying `_` as a capital letter ([#3335][] @apbarrero)
 
 ### Changed
 * [Refactor] [`jsx-indent-props`]: improved readability of the checkNodesIndent function ([#3315][] @caroline223)
@@ -23,6 +24,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
 * [Docs] `sort-comp`: add class component examples ([#3339][] @maurer2)
 
 [#3339]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3339
+[#3335]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3335
 [#3331]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3331
 [#3328]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3328
 [#3327]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3327
diff --git a/lib/util/isFirstLetterCapitalized.js b/lib/util/isFirstLetterCapitalized.js
index f487489b..819edc88 100644
--- a/lib/util/isFirstLetterCapitalized.js
+++ b/lib/util/isFirstLetterCapitalized.js
@@ -6,7 +6,7 @@
  * @returns {Boolean} True if first letter is capitalized.
  */
 function isFirstLetterCapitalized(word) {
-  if (!word) {
+  if (!word || word.charAt(0) === '_') {
     return false;
   }
   const firstLetter = word.charAt(0);


Test patch:
diff --git a/tests/lib/rules/display-name.js b/tests/lib/rules/display-name.js
index 39bdb59c..ba4b9181 100644
--- a/tests/lib/rules/display-name.js
+++ b/tests/lib/rules/display-name.js
@@ -597,6 +597,24 @@ ruleTester.run('display-name', rule, {
           return f(a);
         };`,
     },
+    {
+      // issue #3334
+      code: `
+        obj._property = (a) => {
+          if (a == null) return null;
+          return f(a);
+        };
+      `,
+    },
+    {
+      // issue #3334
+      code: `
+        _variable = (a) => {
+          if (a == null) return null;
+          return f(a);
+        };
+      `,
+    },
     {
       // issue #3303
       code: `
diff --git a/tests/util/isFirstLetterCapitalized.js b/tests/util/isFirstLetterCapitalized.js
index 5ccbfea6..85bdffd1 100644
--- a/tests/util/isFirstLetterCapitalized.js
+++ b/tests/util/isFirstLetterCapitalized.js
@@ -14,6 +14,8 @@ describe('isFirstLetterCapitalized', () => {
   it('should return false for uncapitalized string', () => {
     assert.equal(isFirstLetterCapitalized('isCapitalized'), false);
     assert.equal(isFirstLetterCapitalized('lowercase'), false);
+    assert.equal(isFirstLetterCapitalized('_startsWithUnderscore'), false);
+    assert.equal(isFirstLetterCapitalized('_StartsWithUnderscore'), false);
   });
 
   it('should return true for capitalized string', () => {