Skip to content

Commit 4876d54

Browse files
[Fix] no-unused-state: avoid a crash
Fixes #3240. Co-authored-by: Willy Liao <[email protected]> Co-authored-by: Jordan Harband <[email protected]>
1 parent b9b1bee commit 4876d54

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1313
### Fixed
1414
* [`hook-use-state`]: Allow UPPERCASE setState setter prefixes ([#3244][] @duncanbeevers)
1515
* `propTypes`: add `VFC` to react generic type param map ([#3230][] @dlech)
16+
* [`no-unused-state`]: avoid a crash ([#3258][] @WillyLiaoWH @ljharb)
1617

1718
### Changed
1819
* [readme] remove global usage and eslint version from readme ([#3254][] @aladdin-add)
@@ -22,6 +23,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
2223
[#3261]: https://github.com/yannickcr/eslint-plugin-react/pull/3261
2324
[#3260]: https://github.com/yannickcr/eslint-plugin-react/pull/3260
2425
[#3259]: https://github.com/yannickcr/eslint-plugin-react/pull/3259
26+
[#3258]: https://github.com/yannickcr/eslint-plugin-react/pull/3258
2527
[#3254]: https://github.com/yannickcr/eslint-plugin-react/pull/3254
2628
[#3251]: https://github.com/yannickcr/eslint-plugin-react/pull/3251
2729
[#3244]: https://github.com/yannickcr/eslint-plugin-react/pull/3244

lib/rules/no-unused-state.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ module.exports = {
161161
// Adds the name of the given node as a used state field if the node is an
162162
// Identifier or a Literal. Other node types are ignored.
163163
function addUsedStateField(node) {
164+
if (!classInfo) {
165+
return;
166+
}
164167
const name = getName(node);
165168
if (name) {
166169
classInfo.usedStateFields.add(name);
@@ -371,7 +374,7 @@ module.exports = {
371374
}
372375
const scope = childScope.variableScope.childScopes.find((x) => x.block === node.value);
373376
const stateArg = node.value.params[1]; // probably "state"
374-
if (!scope.variables) {
377+
if (!scope || !scope.variables) {
375378
return;
376379
}
377380
const argVar = scope.variables.find((x) => x.name === stateArg.name);

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

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -989,16 +989,16 @@ eslintTester.run('no-unused-state', rule, {
989989
semver.satisfies(tsEslintVersion, '>= 5') ? {
990990
code: `
991991
interface Props {}
992-
992+
993993
interface State {
994994
flag: boolean;
995995
}
996-
996+
997997
export default class RuleTest extends React.Component<Props, State> {
998998
readonly state: State = {
999999
flag: false,
10001000
};
1001-
1001+
10021002
static getDerivedStateFromProps = (props: Props, state: State) => {
10031003
const newState: Partial<State> = {};
10041004
if (!state.flag) {
@@ -1030,7 +1030,7 @@ eslintTester.run('no-unused-state', rule, {
10301030
class KarmaRefundPillComponent extends GenericPillComponent {
10311031
renderContent = () => {
10321032
const { action } = this.props
1033-
1033+
10341034
return (
10351035
<Box fontSize={[1]} mx={[2]} minWidth="10px" minHeight="26px" alignItems="center">
10361036
<FormattedText
@@ -1064,6 +1064,40 @@ eslintTester.run('no-unused-state', rule, {
10641064
parserOptions: {
10651065
sourceType: 'module',
10661066
},
1067+
},
1068+
{
1069+
code: `
1070+
import React, { PureComponent } from 'react';
1071+
1072+
class TestNoUnusedState extends React.Component {
1073+
constructor(props) {
1074+
super(props);
1075+
this.state = {
1076+
id: null,
1077+
};
1078+
}
1079+
1080+
static getDerivedStateFromProps = (props, state) => {
1081+
if (state.id !== props.id) {
1082+
return {
1083+
id: props.id,
1084+
};
1085+
}
1086+
1087+
return null;
1088+
};
1089+
1090+
render() {
1091+
return <h1>{this.state.id}</h1>;
1092+
}
1093+
}
1094+
1095+
export default TestNoUnusedState;
1096+
`,
1097+
features: ['class fields'],
1098+
parserOptions: {
1099+
sourceType: 'module',
1100+
},
10671101
}
10681102
)),
10691103

0 commit comments

Comments
 (0)