From 1948765c2670d68ae9e3f8826f7ff2ad1c25cb72 Mon Sep 17 00:00:00 2001 From: TildaDares Date: Mon, 4 Jul 2022 21:28:19 +0100 Subject: [PATCH] [Fix] `jsx-key`: catch key errors inside conditional statements Fixes #3117 --- CHANGELOG.md | 2 ++ lib/rules/jsx-key.js | 33 +++++++++++++++++++----- tests/lib/rules/jsx-key.js | 52 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52dc09f1ea..b08d587b56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,12 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ### Fixed * [`jsx-no-literals`]: properly error on children with noAttributeStrings: true ([#3317][] @TildaDares) +* [`jsx-key`]: catch key errors inside conditional statements ([#3320][] @TildaDates) ### Changed * [Refactor] [`jsx-indent-props`]: improved readability of the checkNodesIndent function ([#3315][] @caroline223) +[#3320]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3320 [#3317]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3317 [#3315]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3315 [#3311]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3311 diff --git a/lib/rules/jsx-key.js b/lib/rules/jsx-key.js index 65f9e37ea0..2b61cc20a1 100644 --- a/lib/rules/jsx-key.js +++ b/lib/rules/jsx-key.js @@ -86,8 +86,28 @@ module.exports = { } } - function getReturnStatement(body) { - return body.filter((item) => item.type === 'ReturnStatement')[0]; + function getReturnStatements(node) { + const returnStatements = arguments[1] || []; + if (node.type === 'IfStatement') { + if (node.consequent) { + getReturnStatements(node.consequent, returnStatements); + } + if (node.alternate) { + getReturnStatements(node.alternate, returnStatements); + } + } else { + node.body.forEach((item) => { + if (item.type === 'IfStatement') { + getReturnStatements(item, returnStatements); + } + + if (item.type === 'ReturnStatement') { + returnStatements.push(item); + } + }); + } + + return returnStatements; } function isKeyAfterSpread(attributes) { @@ -189,10 +209,11 @@ module.exports = { if (isFn || isArrFn) { if (fn.body.type === 'BlockStatement') { - const returnStatement = getReturnStatement(fn.body.body); - if (returnStatement && returnStatement.argument) { - checkIteratorElement(returnStatement.argument); - } + getReturnStatements(fn.body) + .filter((returnStatement) => returnStatement && returnStatement.argument) + .forEach((returnStatement) => { + checkIteratorElement(returnStatement.argument); + }); } } }, diff --git a/tests/lib/rules/jsx-key.js b/tests/lib/rules/jsx-key.js index 04103f45df..4dae8973f3 100644 --- a/tests/lib/rules/jsx-key.js +++ b/tests/lib/rules/jsx-key.js @@ -230,5 +230,57 @@ ruleTester.run('jsx-key', rule, { { messageId: 'nonUniqueKeys', line: 5 }, ], }, + { + code: ` + const Test = () => { + const list = [1, 2, 3, 4, 5]; + + return ( +
+ {list.map(item => { + if (item < 2) { + return
{item}
; + } + + return
; + })} +
+ ); + }; + `, + errors: [ + { messageId: 'missingIterKey' }, + { messageId: 'missingIterKey' }, + ], + }, + { + code: ` + const TestO = () => { + const list = [1, 2, 3, 4, 5]; + + return ( +
+ {list.map(item => { + if (item < 2) { + return
{item}
; + } else if (item < 5) { + return
+ } else { + return
+ } + + return
; + })} +
+ ); + }; + `, + errors: [ + { messageId: 'missingIterKey' }, + { messageId: 'missingIterKey' }, + { messageId: 'missingIterKey' }, + { messageId: 'missingIterKey' }, + ], + }, ]), });