Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions lib/rules/no-unused-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ function uncast(node) {
// method definitions, ObjectExpression property keys).
function getName(node) {
node = uncast(node);
if (node.type === 'Identifier') {
const type = node.type;

if (type === 'Identifier') {
return node.name;
} else if (node.type === 'Literal') {
} else if (type === 'Literal') {
return String(node.value);
} else if (type === 'TemplateLiteral' && node.expressions.length === 0) {
return node.quasis[0].value.raw;
}
return null;
}
Expand Down Expand Up @@ -92,7 +96,15 @@ module.exports = {
// current set of state fields.
function addStateFields(node) {
for (const prop of node.properties) {
if (prop.type === 'Property' && getName(prop.key) !== null) {
const key = prop.key;

if (
prop.type === 'Property' &&
(key.type === 'Literal' ||
(key.type === 'TemplateLiteral' && key.expressions.length === 0) ||
(prop.computed === false && key.type === 'Identifier')) &&
getName(prop.key) !== null
) {
classInfo.stateFields.add(prop);
}
}
Expand Down
232 changes: 232 additions & 0 deletions tests/lib/rules/no-unused-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,70 @@ eslintTester.run('no-unused-state', rule, {
return <SomeComponent foo={this.state.foo} />;
}
});`,
`var ComputedKeyFromVariableTest = createReactClass({
getInitialState: function() {
return { [foo]: 0 };
},
render: function() {
return <SomeComponent />;
}
});`,
`var ComputedKeyFromBooleanLiteralTest = createReactClass({
getInitialState: function() {
return { [true]: 0 };
},
render: function() {
return <SomeComponent foo={this.state[true]} />;
}
});`,
`var ComputedKeyFromNumberLiteralTest = createReactClass({
getInitialState: function() {
return { [123]: 0 };
},
render: function() {
return <SomeComponent foo={this.state[123]} />;
}
});`,
`var ComputedKeyFromExpressionTest = createReactClass({
getInitialState: function() {
return { [foo + bar]: 0 };
},
render: function() {
return <SomeComponent />;
}
});`,
`var ComputedKeyFromBinaryExpressionTest = createReactClass({
getInitialState: function() {
return { ['foo' + 'bar' * 8]: 0 };
},
render: function() {
return <SomeComponent />;
}
});`,
`var ComputedKeyFromStringLiteralTest = createReactClass({
getInitialState: function() {
return { ['foo']: 0 };
},
render: function() {
return <SomeComponent foo={this.state.foo} />;
}
});`,
`var ComputedKeyFromTemplateLiteralTest = createReactClass({
getInitialState: function() {
return { [\`foo\${bar}\`]: 0 };
},
render: function() {
return <SomeComponent />;
}
});`,
`var ComputedKeyFromTemplateLiteralTest = createReactClass({
getInitialState: function() {
return { [\`foo\`]: 0 };
},
render: function() {
return <SomeComponent foo={this.state['foo']} />;
}
});`,
`var GetInitialStateMethodTest = createReactClass({
getInitialState() {
return { foo: 0 };
Expand Down Expand Up @@ -86,6 +150,70 @@ eslintTester.run('no-unused-state', rule, {
return <SomeComponent foo={this.state.foo} />;
}
}`,
`class ComputedKeyFromVariableTest extends React.Component {
constructor() {
this.state = { [foo]: 0 };
}
render() {
return <SomeComponent />;
}
}`,
`class ComputedKeyFromBooleanLiteralTest extends React.Component {
constructor() {
this.state = { [false]: 0 };
}
render() {
return <SomeComponent foo={this.state['false']} />;
}
}`,
`class ComputedKeyFromNumberLiteralTest extends React.Component {
constructor() {
this.state = { [345]: 0 };
}
render() {
return <SomeComponent foo={this.state[345]} />;
}
}`,
`class ComputedKeyFromExpressionTest extends React.Component {
constructor() {
this.state = { [foo + bar]: 0 };
}
render() {
return <SomeComponent />;
}
}`,
`class ComputedKeyFromBinaryExpressionTest extends React.Component {
constructor() {
this.state = { [1 + 2 * 8]: 0 };
}
render() {
return <SomeComponent />;
}
}`,
`class ComputedKeyFromStringLiteralTest extends React.Component {
constructor() {
this.state = { ['foo']: 0 };
}
render() {
return <SomeComponent foo={this.state.foo} />;
}
}`,
`class ComputedKeyFromTemplateLiteralTest extends React.Component {
constructor() {
this.state = { [\`foo\${bar}\`]: 0 };
}
render() {
return <SomeComponent />;
}
}`,
`class ComputedKeyFromTemplateLiteralTest extends React.Component {
constructor() {
this.state = { [\`foo\`]: 0 };
}
render() {
return <SomeComponent foo={this.state.foo} />;
}
}`,
`class SetStateTest extends React.Component {
onFooChange(newFoo) {
this.setState({ foo: newFoo });
Expand Down Expand Up @@ -284,6 +412,50 @@ eslintTester.run('no-unused-state', rule, {
})`,
errors: getErrorMessages(['foo'])
},
{
code: `var UnusedComputedStringLiteralKeyStateTest = createReactClass({
getInitialState: function() {
return { ['foo']: 0 };
},
render: function() {
return <SomeComponent />;
}
})`,
errors: getErrorMessages(['foo'])
},
{
code: `var UnusedComputedTemplateLiteralKeyStateTest = createReactClass({
getInitialState: function() {
return { [\`foo\`]: 0 };
},
render: function() {
return <SomeComponent />;
}
})`,
errors: getErrorMessages(['foo'])
},
{
code: `var UnusedComputedNumberLiteralKeyStateTest = createReactClass({
getInitialState: function() {
return { [123]: 0 };
},
render: function() {
return <SomeComponent />;
}
})`,
errors: getErrorMessages(['123'])
},
{
code: `var UnusedComputedBooleanLiteralKeyStateTest = createReactClass({
getInitialState: function() {
return { [true]: 0 };
},
render: function() {
return <SomeComponent />;
}
})`,
errors: getErrorMessages(['true'])
},
{
code: `var UnusedGetInitialStateMethodTest = createReactClass({
getInitialState() {
Expand Down Expand Up @@ -338,6 +510,66 @@ eslintTester.run('no-unused-state', rule, {
errors: getErrorMessages(['foo']),
parser: 'babel-eslint'
},
{
code: `class UnusedComputedStringLiteralKeyStateTest extends React.Component {
state = { ['foo']: 0 };
render() {
return <SomeComponent />;
}
}`,
errors: getErrorMessages(['foo']),
parser: 'babel-eslint'
},
{
code: `class UnusedComputedTemplateLiteralKeyStateTest extends React.Component {
state = { [\`foo\`]: 0 };
render() {
return <SomeComponent />;
}
}`,
errors: getErrorMessages(['foo']),
parser: 'babel-eslint'
},
{
code: `class UnusedComputedTemplateLiteralKeyStateTest extends React.Component {
state = { [\`foo \\n bar\`]: 0 };
render() {
return <SomeComponent />;
}
}`,
errors: getErrorMessages(['foo \\n bar']),
parser: 'babel-eslint'
},
{
code: `class UnusedComputedBooleanLiteralKeyStateTest extends React.Component {
state = { [true]: 0 };
render() {
return <SomeComponent />;
}
}`,
errors: getErrorMessages(['true']),
parser: 'babel-eslint'
},
{
code: `class UnusedComputedNumberLiteralKeyStateTest extends React.Component {
state = { [123]: 0 };
render() {
return <SomeComponent />;
}
}`,
errors: getErrorMessages(['123']),
parser: 'babel-eslint'
},
{
code: `class UnusedComputedFloatLiteralKeyStateTest extends React.Component {
state = { [123.12]: 0 };
render() {
return <SomeComponent />;
}
}`,
errors: getErrorMessages(['123.12']),
parser: 'babel-eslint'
},
{
code: `class UnusedStateWhenPropsAreSpreadTest extends React.Component {
constructor() {
Expand Down