Skip to content

Commit 096ce98

Browse files
authored
Merge pull request jsx-eslint#1394 from jackyho112/ignore-computed-property-keys-for-no-unused-state-rule
[no-unused-state] Ignore computed property keys for no unused state rule
2 parents 6106e62 + 195d008 commit 096ce98

File tree

2 files changed

+247
-3
lines changed

2 files changed

+247
-3
lines changed

lib/rules/no-unused-state.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,14 @@ function uncast(node) {
2525
// method definitions, ObjectExpression property keys).
2626
function getName(node) {
2727
node = uncast(node);
28-
if (node.type === 'Identifier') {
28+
const type = node.type;
29+
30+
if (type === 'Identifier') {
2931
return node.name;
30-
} else if (node.type === 'Literal') {
32+
} else if (type === 'Literal') {
3133
return String(node.value);
34+
} else if (type === 'TemplateLiteral' && node.expressions.length === 0) {
35+
return node.quasis[0].value.raw;
3236
}
3337
return null;
3438
}
@@ -92,7 +96,15 @@ module.exports = {
9296
// current set of state fields.
9397
function addStateFields(node) {
9498
for (const prop of node.properties) {
95-
if (prop.type === 'Property' && getName(prop.key) !== null) {
99+
const key = prop.key;
100+
101+
if (
102+
prop.type === 'Property' &&
103+
(key.type === 'Literal' ||
104+
(key.type === 'TemplateLiteral' && key.expressions.length === 0) ||
105+
(prop.computed === false && key.type === 'Identifier')) &&
106+
getName(prop.key) !== null
107+
) {
96108
classInfo.stateFields.add(prop);
97109
}
98110
}

tests/lib/rules/no-unused-state.js

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,70 @@ eslintTester.run('no-unused-state', rule, {
4646
return <SomeComponent foo={this.state.foo} />;
4747
}
4848
});`,
49+
`var ComputedKeyFromVariableTest = createReactClass({
50+
getInitialState: function() {
51+
return { [foo]: 0 };
52+
},
53+
render: function() {
54+
return <SomeComponent />;
55+
}
56+
});`,
57+
`var ComputedKeyFromBooleanLiteralTest = createReactClass({
58+
getInitialState: function() {
59+
return { [true]: 0 };
60+
},
61+
render: function() {
62+
return <SomeComponent foo={this.state[true]} />;
63+
}
64+
});`,
65+
`var ComputedKeyFromNumberLiteralTest = createReactClass({
66+
getInitialState: function() {
67+
return { [123]: 0 };
68+
},
69+
render: function() {
70+
return <SomeComponent foo={this.state[123]} />;
71+
}
72+
});`,
73+
`var ComputedKeyFromExpressionTest = createReactClass({
74+
getInitialState: function() {
75+
return { [foo + bar]: 0 };
76+
},
77+
render: function() {
78+
return <SomeComponent />;
79+
}
80+
});`,
81+
`var ComputedKeyFromBinaryExpressionTest = createReactClass({
82+
getInitialState: function() {
83+
return { ['foo' + 'bar' * 8]: 0 };
84+
},
85+
render: function() {
86+
return <SomeComponent />;
87+
}
88+
});`,
89+
`var ComputedKeyFromStringLiteralTest = createReactClass({
90+
getInitialState: function() {
91+
return { ['foo']: 0 };
92+
},
93+
render: function() {
94+
return <SomeComponent foo={this.state.foo} />;
95+
}
96+
});`,
97+
`var ComputedKeyFromTemplateLiteralTest = createReactClass({
98+
getInitialState: function() {
99+
return { [\`foo\${bar}\`]: 0 };
100+
},
101+
render: function() {
102+
return <SomeComponent />;
103+
}
104+
});`,
105+
`var ComputedKeyFromTemplateLiteralTest = createReactClass({
106+
getInitialState: function() {
107+
return { [\`foo\`]: 0 };
108+
},
109+
render: function() {
110+
return <SomeComponent foo={this.state['foo']} />;
111+
}
112+
});`,
49113
`var GetInitialStateMethodTest = createReactClass({
50114
getInitialState() {
51115
return { foo: 0 };
@@ -86,6 +150,70 @@ eslintTester.run('no-unused-state', rule, {
86150
return <SomeComponent foo={this.state.foo} />;
87151
}
88152
}`,
153+
`class ComputedKeyFromVariableTest extends React.Component {
154+
constructor() {
155+
this.state = { [foo]: 0 };
156+
}
157+
render() {
158+
return <SomeComponent />;
159+
}
160+
}`,
161+
`class ComputedKeyFromBooleanLiteralTest extends React.Component {
162+
constructor() {
163+
this.state = { [false]: 0 };
164+
}
165+
render() {
166+
return <SomeComponent foo={this.state['false']} />;
167+
}
168+
}`,
169+
`class ComputedKeyFromNumberLiteralTest extends React.Component {
170+
constructor() {
171+
this.state = { [345]: 0 };
172+
}
173+
render() {
174+
return <SomeComponent foo={this.state[345]} />;
175+
}
176+
}`,
177+
`class ComputedKeyFromExpressionTest extends React.Component {
178+
constructor() {
179+
this.state = { [foo + bar]: 0 };
180+
}
181+
render() {
182+
return <SomeComponent />;
183+
}
184+
}`,
185+
`class ComputedKeyFromBinaryExpressionTest extends React.Component {
186+
constructor() {
187+
this.state = { [1 + 2 * 8]: 0 };
188+
}
189+
render() {
190+
return <SomeComponent />;
191+
}
192+
}`,
193+
`class ComputedKeyFromStringLiteralTest extends React.Component {
194+
constructor() {
195+
this.state = { ['foo']: 0 };
196+
}
197+
render() {
198+
return <SomeComponent foo={this.state.foo} />;
199+
}
200+
}`,
201+
`class ComputedKeyFromTemplateLiteralTest extends React.Component {
202+
constructor() {
203+
this.state = { [\`foo\${bar}\`]: 0 };
204+
}
205+
render() {
206+
return <SomeComponent />;
207+
}
208+
}`,
209+
`class ComputedKeyFromTemplateLiteralTest extends React.Component {
210+
constructor() {
211+
this.state = { [\`foo\`]: 0 };
212+
}
213+
render() {
214+
return <SomeComponent foo={this.state.foo} />;
215+
}
216+
}`,
89217
`class SetStateTest extends React.Component {
90218
onFooChange(newFoo) {
91219
this.setState({ foo: newFoo });
@@ -284,6 +412,50 @@ eslintTester.run('no-unused-state', rule, {
284412
})`,
285413
errors: getErrorMessages(['foo'])
286414
},
415+
{
416+
code: `var UnusedComputedStringLiteralKeyStateTest = createReactClass({
417+
getInitialState: function() {
418+
return { ['foo']: 0 };
419+
},
420+
render: function() {
421+
return <SomeComponent />;
422+
}
423+
})`,
424+
errors: getErrorMessages(['foo'])
425+
},
426+
{
427+
code: `var UnusedComputedTemplateLiteralKeyStateTest = createReactClass({
428+
getInitialState: function() {
429+
return { [\`foo\`]: 0 };
430+
},
431+
render: function() {
432+
return <SomeComponent />;
433+
}
434+
})`,
435+
errors: getErrorMessages(['foo'])
436+
},
437+
{
438+
code: `var UnusedComputedNumberLiteralKeyStateTest = createReactClass({
439+
getInitialState: function() {
440+
return { [123]: 0 };
441+
},
442+
render: function() {
443+
return <SomeComponent />;
444+
}
445+
})`,
446+
errors: getErrorMessages(['123'])
447+
},
448+
{
449+
code: `var UnusedComputedBooleanLiteralKeyStateTest = createReactClass({
450+
getInitialState: function() {
451+
return { [true]: 0 };
452+
},
453+
render: function() {
454+
return <SomeComponent />;
455+
}
456+
})`,
457+
errors: getErrorMessages(['true'])
458+
},
287459
{
288460
code: `var UnusedGetInitialStateMethodTest = createReactClass({
289461
getInitialState() {
@@ -338,6 +510,66 @@ eslintTester.run('no-unused-state', rule, {
338510
errors: getErrorMessages(['foo']),
339511
parser: 'babel-eslint'
340512
},
513+
{
514+
code: `class UnusedComputedStringLiteralKeyStateTest extends React.Component {
515+
state = { ['foo']: 0 };
516+
render() {
517+
return <SomeComponent />;
518+
}
519+
}`,
520+
errors: getErrorMessages(['foo']),
521+
parser: 'babel-eslint'
522+
},
523+
{
524+
code: `class UnusedComputedTemplateLiteralKeyStateTest extends React.Component {
525+
state = { [\`foo\`]: 0 };
526+
render() {
527+
return <SomeComponent />;
528+
}
529+
}`,
530+
errors: getErrorMessages(['foo']),
531+
parser: 'babel-eslint'
532+
},
533+
{
534+
code: `class UnusedComputedTemplateLiteralKeyStateTest extends React.Component {
535+
state = { [\`foo \\n bar\`]: 0 };
536+
render() {
537+
return <SomeComponent />;
538+
}
539+
}`,
540+
errors: getErrorMessages(['foo \\n bar']),
541+
parser: 'babel-eslint'
542+
},
543+
{
544+
code: `class UnusedComputedBooleanLiteralKeyStateTest extends React.Component {
545+
state = { [true]: 0 };
546+
render() {
547+
return <SomeComponent />;
548+
}
549+
}`,
550+
errors: getErrorMessages(['true']),
551+
parser: 'babel-eslint'
552+
},
553+
{
554+
code: `class UnusedComputedNumberLiteralKeyStateTest extends React.Component {
555+
state = { [123]: 0 };
556+
render() {
557+
return <SomeComponent />;
558+
}
559+
}`,
560+
errors: getErrorMessages(['123']),
561+
parser: 'babel-eslint'
562+
},
563+
{
564+
code: `class UnusedComputedFloatLiteralKeyStateTest extends React.Component {
565+
state = { [123.12]: 0 };
566+
render() {
567+
return <SomeComponent />;
568+
}
569+
}`,
570+
errors: getErrorMessages(['123.12']),
571+
parser: 'babel-eslint'
572+
},
341573
{
342574
code: `class UnusedStateWhenPropsAreSpreadTest extends React.Component {
343575
constructor() {

0 commit comments

Comments
 (0)