From 9e670c75ba2088f7c0ccb93363f7728d5c38ba8a Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Tue, 17 Mar 2015 11:06:30 -0400 Subject: [PATCH 1/2] Modified no-did-X-set-state rules to enforce only for direct calls to this.setState; references/assignment are allowed. Extra credit: ensure the reference is not used to be called thereafter. (not part of this commit.) --- lib/rules/no-did-mount-set-state.js | 12 ++++++++---- lib/rules/no-did-update-set-state.js | 12 ++++++++---- tests/lib/rules/no-did-mount-set-state.js | 13 +++++++++++++ tests/lib/rules/no-did-update-set-state.js | 13 +++++++++++++ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/lib/rules/no-did-mount-set-state.js b/lib/rules/no-did-mount-set-state.js index c954e5971e..0bb4bac893 100644 --- a/lib/rules/no-did-mount-set-state.js +++ b/lib/rules/no-did-mount-set-state.js @@ -16,16 +16,20 @@ module.exports = function(context) { return { - 'MemberExpression': function(node) { - if (node.object.type !== 'ThisExpression' || node.property.name !== 'setState') { + 'CallExpression': function(node) { + var callee = node.callee; + if (callee.type !== 'MemberExpression') { return; } - var ancestors = context.getAncestors(node); + if (callee.object.type !== 'ThisExpression' || callee.property.name !== 'setState') { + return; + } + var ancestors = context.getAncestors(callee); for (var i = 0, j = ancestors.length; i < j; i++) { if (ancestors[i].type !== 'Property' || ancestors[i].key.name !== 'componentDidMount') { continue; } - context.report(node, 'Do not use setState in componentDidMount'); + context.report(callee, 'Do not use setState in componentDidMount'); } } }; diff --git a/lib/rules/no-did-update-set-state.js b/lib/rules/no-did-update-set-state.js index 1c14b49492..721e856dc2 100644 --- a/lib/rules/no-did-update-set-state.js +++ b/lib/rules/no-did-update-set-state.js @@ -16,16 +16,20 @@ module.exports = function(context) { return { - 'MemberExpression': function(node) { - if (node.object.type !== 'ThisExpression' || node.property.name !== 'setState') { + 'CallExpression': function(node) { + var callee = node.callee; + if (callee.type !== 'MemberExpression') { return; } - var ancestors = context.getAncestors(node); + if (callee.object.type !== 'ThisExpression' || callee.property.name !== 'setState') { + return; + } + var ancestors = context.getAncestors(callee); for (var i = 0, j = ancestors.length; i < j; i++) { if (ancestors[i].type !== 'Property' || ancestors[i].key.name !== 'componentDidUpdate') { continue; } - context.report(node, 'Do not use setState in componentDidUpdate'); + context.report(callee, 'Do not use setState in componentDidUpdate'); } } }; diff --git a/tests/lib/rules/no-did-mount-set-state.js b/tests/lib/rules/no-did-mount-set-state.js index 30b061baf0..68ed5d7a1c 100644 --- a/tests/lib/rules/no-did-mount-set-state.js +++ b/tests/lib/rules/no-did-mount-set-state.js @@ -40,6 +40,19 @@ eslintTester.addRuleTest('lib/rules/no-did-mount-set-state', { ecmaFeatures: { jsx: true } + }, { + code: '\ + var Hello = React.createClass({\ + componentDidMount: function() {\ + this.someHandler = this.setState;\ + },\ + render: function() {\ + return
Hello {this.props.name}
;\ + }\ + });', + ecmaFeatures: { + jsx: true + } } ], diff --git a/tests/lib/rules/no-did-update-set-state.js b/tests/lib/rules/no-did-update-set-state.js index f41990f33a..b9bea843eb 100644 --- a/tests/lib/rules/no-did-update-set-state.js +++ b/tests/lib/rules/no-did-update-set-state.js @@ -40,6 +40,19 @@ eslintTester.addRuleTest('lib/rules/no-did-update-set-state', { ecmaFeatures: { jsx: true } + }, { + code: '\ + var Hello = React.createClass({\ + componentDidUpdate: function() {\ + this.someHandler = this.setState;\ + },\ + render: function() {\ + return
Hello {this.props.name}
;\ + }\ + });', + ecmaFeatures: { + jsx: true + } } ], From e42ba310aa7bda762889c6bc597414380013278d Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Tue, 17 Mar 2015 11:32:40 -0400 Subject: [PATCH 2/2] Added trivial non-member function call expression to appease the code coverage gods. --- tests/lib/rules/no-did-mount-set-state.js | 1 + tests/lib/rules/no-did-update-set-state.js | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/lib/rules/no-did-mount-set-state.js b/tests/lib/rules/no-did-mount-set-state.js index 68ed5d7a1c..7cc67f3b8c 100644 --- a/tests/lib/rules/no-did-mount-set-state.js +++ b/tests/lib/rules/no-did-mount-set-state.js @@ -44,6 +44,7 @@ eslintTester.addRuleTest('lib/rules/no-did-mount-set-state', { code: '\ var Hello = React.createClass({\ componentDidMount: function() {\ + someNonMemberFunction(arg);\ this.someHandler = this.setState;\ },\ render: function() {\ diff --git a/tests/lib/rules/no-did-update-set-state.js b/tests/lib/rules/no-did-update-set-state.js index b9bea843eb..8021937012 100644 --- a/tests/lib/rules/no-did-update-set-state.js +++ b/tests/lib/rules/no-did-update-set-state.js @@ -44,6 +44,7 @@ eslintTester.addRuleTest('lib/rules/no-did-update-set-state', { code: '\ var Hello = React.createClass({\ componentDidUpdate: function() {\ + someNonMemberFunction(arg);\ this.someHandler = this.setState;\ },\ render: function() {\