Skip to content

Commit b1024c0

Browse files
committed
Fix a case where left side of assignment is not MemberExpression
This commit also move `isStateMemberExpression` from `no-direct-mutation-state` rule into `util/Components` so that the logic could be share with other rules.
1 parent 3516a81 commit b1024c0

File tree

4 files changed

+37
-13
lines changed

4 files changed

+37
-13
lines changed

lib/rules/no-direct-mutation-state.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,6 @@ module.exports = {
5959
return node;
6060
}
6161

62-
/**
63-
* Determine if this MemberExpression is for `this.state`
64-
* @param {Object} node The node to process
65-
* @returns {Boolean}
66-
*/
67-
function isStateMemberExpression(node) {
68-
return node.object.type === 'ThisExpression' && node.property.name === 'state';
69-
}
70-
7162
/**
7263
* Determine if we should currently ignore assignments in this component.
7364
* @param {?Object} component The component to process
@@ -101,7 +92,7 @@ module.exports = {
10192
return;
10293
}
10394
const item = getOuterMemberExpression(node.left);
104-
if (isStateMemberExpression(item)) {
95+
if (utils.isStateMemberExpression(item)) {
10596
const mutations = (component && component.mutations) || [];
10697
mutations.push(node.left.object);
10798
components.set(node, {
@@ -117,7 +108,7 @@ module.exports = {
117108
return;
118109
}
119110
const item = getOuterMemberExpression(node.argument);
120-
if (isStateMemberExpression(item)) {
111+
if (utils.isStateMemberExpression(item)) {
121112
const mutations = (component && component.mutations) || [];
122113
mutations.push(item);
123114
components.set(node, {

lib/rules/state-in-constructor.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ module.exports = {
4343
AssignmentExpression(node) {
4444
if (
4545
option === 'never' &&
46-
node.left.object.type === 'ThisExpression' &&
47-
node.left.property.name === 'state' &&
46+
utils.isStateMemberExpression(node.left) &&
4847
utils.inConstructor() &&
4948
utils.getParentES6Component()
5049
) {

lib/util/Components.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,15 @@ function componentRule(rule, context) {
321321
return false;
322322
},
323323

324+
/**
325+
* Determine if the node is MemberExpression of `this.state`
326+
* @param {Object} node The node to process
327+
* @returns {Boolean}
328+
*/
329+
isStateMemberExpression: function(node) {
330+
return node.type === 'MemberExpression' && node.object.type === 'ThisExpression' && node.property.name === 'state';
331+
},
332+
324333
getReturnPropertyAndNode(ASTnode) {
325334
let property;
326335
let node = ASTnode;

tests/lib/rules/state-in-constructor.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,31 @@ ruleTester.run('state-in-constructor', rule, {
198198
}
199199
}
200200
`
201+
}, {
202+
code: `
203+
class Foo extends React.Component {
204+
constructor(props) {
205+
super(props)
206+
foobar = { bar: 0 }
207+
}
208+
render() {
209+
return <div>Foo</div>
210+
}
211+
}
212+
`
213+
}, {
214+
code: `
215+
class Foo extends React.Component {
216+
constructor(props) {
217+
super(props)
218+
foobar = { bar: 0 }
219+
}
220+
render() {
221+
return <div>Foo</div>
222+
}
223+
}
224+
`,
225+
options: ['never']
201226
}],
202227

203228
invalid: [{

0 commit comments

Comments
 (0)