Skip to content

Commit 68d6384

Browse files
Fix no-this-in-sfc for class properties
Fixed jsx-eslint#1960
1 parent bd083bf commit 68d6384

File tree

2 files changed

+32
-10
lines changed

2 files changed

+32
-10
lines changed

lib/util/Components.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -456,15 +456,16 @@ function componentRule(rule, context) {
456456
let scope = context.getScope();
457457
while (scope) {
458458
const node = scope.block;
459-
const isClass = node.type === 'ClassExpression';
460459
const isFunction = /Function/.test(node.type); // Functions
461460
const isArrowFunction = node.type === 'ArrowFunctionExpression';
462-
let functionScope = scope;
461+
let enclosingScope = scope;
463462
if (isArrowFunction) {
464-
functionScope = utils.getParentFunctionScope(scope);
463+
enclosingScope = utils.getArrowFunctionScope(scope);
465464
}
466-
const methodNode = functionScope && functionScope.block.parent;
467-
const isMethod = methodNode && methodNode.type === 'MethodDefinition'; // Classes methods
465+
const enclosingScopeType = enclosingScope && enclosingScope.block.type;
466+
const enclosingScopeParent = enclosingScope && enclosingScope.block.parent;
467+
const isClass = enclosingScopeType === 'ClassDeclaration' || enclosingScopeType === 'ClassExpression';
468+
const isMethod = enclosingScopeParent && enclosingScopeParent.type === 'MethodDefinition'; // Classes methods
468469
const isArgument = node.parent && node.parent.type === 'CallExpression'; // Arguments (callback, etc.)
469470
// Attribute Expressions inside JSX Elements (<button onClick={() => props.handleClick()}></button>)
470471
const isJSXExpressionContainer = node.parent && node.parent.type === 'JSXExpressionContainer';
@@ -482,15 +483,16 @@ function componentRule(rule, context) {
482483
},
483484

484485
/**
485-
* Get a parent scope created by a FunctionExpression or FunctionDeclaration
486-
* @param {Scope} scope The child scope
487-
* @returns {Scope} A parent function scope
486+
* Get an enclosing scope used to find `this` value by an arrow function
487+
* @param {Scope} scope Current scope
488+
* @returns {Scope} An enclosing scope used by an arrow function
488489
*/
489-
getParentFunctionScope(scope) {
490+
getArrowFunctionScope(scope) {
490491
scope = scope.upper;
491492
while (scope) {
492493
const type = scope.block.type;
493-
if (type === 'FunctionExpression' || type === 'FunctionDeclaration') {
494+
if (type === 'FunctionExpression' || type === 'FunctionDeclaration'
495+
|| type === 'ClassDeclaration' || type === 'ClassExpression') {
494496
return scope;
495497
}
496498
scope = scope.upper;

tests/lib/rules/no-this-in-sfc.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ const ERROR_MESSAGE = 'Stateless functional components should not use this';
1616
const rule = require('../../../lib/rules/no-this-in-sfc');
1717
const RuleTester = require('eslint').RuleTester;
1818

19+
require('babel-eslint');
20+
1921
const parserOptions = {
2022
ecmaVersion: 2018,
2123
sourceType: 'module',
@@ -119,6 +121,24 @@ ruleTester.run('no-this-in-sfc', rule, {
119121
};
120122
}
121123
}`
124+
}, {
125+
code: `
126+
class Foo {
127+
bar = () => {
128+
this.something();
129+
return null;
130+
};
131+
}`,
132+
parser: 'babel-eslint'
133+
}, {
134+
code: `
135+
class Foo {
136+
bar = () => () => {
137+
this.something();
138+
return null;
139+
};
140+
}`,
141+
parser: 'babel-eslint'
122142
}],
123143
invalid: [{
124144
code: `

0 commit comments

Comments
 (0)