Skip to content

Commit

Permalink
[Fix] jsx-key: catch key errors inside conditional statements
Browse files Browse the repository at this point in the history
Fixes #3117
  • Loading branch information
TildaDares authored and ljharb committed Jul 4, 2022
1 parent 7a7bb99 commit 1948765
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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
Expand Down
33 changes: 27 additions & 6 deletions lib/rules/jsx-key.js
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
});
}
}
},
Expand Down
52 changes: 52 additions & 0 deletions tests/lib/rules/jsx-key.js
Expand Up @@ -230,5 +230,57 @@ ruleTester.run('jsx-key', rule, {
{ messageId: 'nonUniqueKeys', line: 5 },
],
},
{
code: `
const Test = () => {
const list = [1, 2, 3, 4, 5];
return (
<div>
{list.map(item => {
if (item < 2) {
return <div>{item}</div>;
}
return <div />;
})}
</div>
);
};
`,
errors: [
{ messageId: 'missingIterKey' },
{ messageId: 'missingIterKey' },
],
},
{
code: `
const TestO = () => {
const list = [1, 2, 3, 4, 5];
return (
<div>
{list.map(item => {
if (item < 2) {
return <div>{item}</div>;
} else if (item < 5) {
return <div></div>
} else {
return <div></div>
}
return <div />;
})}
</div>
);
};
`,
errors: [
{ messageId: 'missingIterKey' },
{ messageId: 'missingIterKey' },
{ messageId: 'missingIterKey' },
{ messageId: 'missingIterKey' },
],
},
]),
});

0 comments on commit 1948765

Please sign in to comment.