diff --git a/lib/rules/no-unused-state.js b/lib/rules/no-unused-state.js
index d4bef8c278..4040d80dc7 100644
--- a/lib/rules/no-unused-state.js
+++ b/lib/rules/no-unused-state.js
@@ -237,6 +237,27 @@ module.exports = {
) {
addStateFields(node.value);
}
+
+ if (
+ !node.static &&
+ node.value &&
+ node.value.type === 'ArrowFunctionExpression'
+ ) {
+ // Create a new set for this.state aliases local to this method.
+ classInfo.aliases = new Set();
+ }
+ },
+
+ 'ClassProperty:exit'(node) {
+ if (
+ classInfo &&
+ !node.static &&
+ node.value &&
+ node.value.type === 'ArrowFunctionExpression'
+ ) {
+ // Forget our set of local aliases.
+ classInfo.aliases = null;
+ }
},
MethodDefinition() {
diff --git a/tests/lib/rules/no-unused-state.js b/tests/lib/rules/no-unused-state.js
index 4fbb8a4f22..62f9599e4c 100644
--- a/tests/lib/rules/no-unused-state.js
+++ b/tests/lib/rules/no-unused-state.js
@@ -387,6 +387,22 @@ eslintTester.run('no-unused-state', rule, {
return ;
}
}`,
+ `class NonRenderClassMethodFalseNegativeTest extends React.Component {
+ constructor() {
+ this.state = { foo: 0, bar: 0 };
+ }
+ doSomething() {
+ const { foo } = this.state;
+ return this.state.foo;
+ }
+ doSomethingElse() {
+ const { state: { bar }} = this;
+ return bar;
+ }
+ render() {
+ return ;
+ }
+ }`,
{
code: `class TypeCastExpressionSpreadFalseNegativeTest extends React.Component {
constructor() {
@@ -397,6 +413,72 @@ eslintTester.run('no-unused-state', rule, {
}
}`,
parser: 'babel-eslint'
+ },
+ {
+ code: `class ArrowFunctionClassMethodDestructuringFalseNegativeTest extends React.Component {
+ constructor() {
+ this.state = { foo: 0 };
+ }
+
+ doSomething = () => {
+ const { state: { foo } } = this;
+
+ return foo;
+ }
+
+ render() {
+ return ;
+ }
+ }`,
+ parser: 'babel-eslint'
+ },
+ {
+ code: `class ArrowFunctionClassMethodWithClassPropertyTransformFalseNegativeTest extends React.Component {
+ state = { foo: 0 };
+
+ doSomething = () => {
+ const { state:{ foo } } = this;
+
+ return foo;
+ }
+
+ render() {
+ return ;
+ }
+ }`,
+ parser: 'babel-eslint'
+ },
+ {
+ code: `class ArrowFunctionClassMethodDeepDestructuringFalseNegativeTest extends React.Component {
+ state = { foo: { bar: 0 } };
+
+ doSomething = () => {
+ const { state: { foo: { bar }}} = this;
+
+ return bar;
+ }
+
+ render() {
+ return ;
+ }
+ }`,
+ parser: 'babel-eslint'
+ },
+ {
+ code: `class ArrowFunctionClassMethodDestructuringAssignmentFalseNegativeTest extends React.Component {
+ state = { foo: 0 };
+
+ doSomething = () => {
+ const { state: { foo: bar }} = this;
+
+ return bar;
+ }
+
+ render() {
+ return ;
+ }
+ }`,
+ parser: 'babel-eslint'
}
],
@@ -642,6 +724,21 @@ eslintTester.run('no-unused-state', rule, {
}`,
errors: getErrorMessages(['foo'])
},
+ {
+ code: `class UnusedStateArrowFunctionMethodTest extends React.Component {
+ constructor() {
+ this.state = { foo: 0 };
+ }
+ doSomething = () => {
+ return null;
+ }
+ render() {
+ return ;
+ }
+ }`,
+ errors: getErrorMessages(['foo']),
+ parser: 'babel-eslint'
+ },
{
code: `class TypeCastExpressionTest extends React.Component {
constructor() {