diff --git a/CHANGELOG.md b/CHANGELOG.md index 82397550fc..9698e30f33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ### Fixed * [`hook-use-state`]: Allow UPPERCASE setState setter prefixes ([#3244][] @duncanbeevers) * `propTypes`: add `VFC` to react generic type param map ([#3230][] @dlech) +* [`no-unused-state`]: avoid a crash ([#3258][] @WillyLiaoWH @ljharb) ### Changed * [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 [#3261]: https://github.com/yannickcr/eslint-plugin-react/pull/3261 [#3260]: https://github.com/yannickcr/eslint-plugin-react/pull/3260 [#3259]: https://github.com/yannickcr/eslint-plugin-react/pull/3259 +[#3258]: https://github.com/yannickcr/eslint-plugin-react/pull/3258 [#3254]: https://github.com/yannickcr/eslint-plugin-react/pull/3254 [#3251]: https://github.com/yannickcr/eslint-plugin-react/pull/3251 [#3244]: https://github.com/yannickcr/eslint-plugin-react/pull/3244 diff --git a/lib/rules/no-unused-state.js b/lib/rules/no-unused-state.js index cf8cbf917f..ed4393f668 100644 --- a/lib/rules/no-unused-state.js +++ b/lib/rules/no-unused-state.js @@ -161,6 +161,9 @@ module.exports = { // Adds the name of the given node as a used state field if the node is an // Identifier or a Literal. Other node types are ignored. function addUsedStateField(node) { + if (!classInfo) { + return; + } const name = getName(node); if (name) { classInfo.usedStateFields.add(name); @@ -371,7 +374,7 @@ module.exports = { } const scope = childScope.variableScope.childScopes.find((x) => x.block === node.value); const stateArg = node.value.params[1]; // probably "state" - if (!scope.variables) { + if (!scope || !scope.variables) { return; } const argVar = scope.variables.find((x) => x.name === stateArg.name); diff --git a/tests/lib/rules/no-unused-state.js b/tests/lib/rules/no-unused-state.js index 8c06060c3c..380296ec4e 100644 --- a/tests/lib/rules/no-unused-state.js +++ b/tests/lib/rules/no-unused-state.js @@ -989,16 +989,16 @@ eslintTester.run('no-unused-state', rule, { semver.satisfies(tsEslintVersion, '>= 5') ? { code: ` interface Props {} - + interface State { flag: boolean; } - + export default class RuleTest extends React.Component { readonly state: State = { flag: false, }; - + static getDerivedStateFromProps = (props: Props, state: State) => { const newState: Partial = {}; if (!state.flag) { @@ -1030,7 +1030,7 @@ eslintTester.run('no-unused-state', rule, { class KarmaRefundPillComponent extends GenericPillComponent { renderContent = () => { const { action } = this.props - + return ( { + if (state.id !== props.id) { + return { + id: props.id, + }; + } + + return null; + }; + + render() { + return

{this.state.id}

; + } + } + + export default TestNoUnusedState; + `, + features: ['class fields'], + parserOptions: { + sourceType: 'module', + }, } )),