Skip to content

Commit 1948765

Browse files
TildaDaresljharb
authored andcommitted
[Fix] jsx-key: catch key errors inside conditional statements
Fixes #3117
1 parent 7a7bb99 commit 1948765

File tree

3 files changed

+81
-6
lines changed

3 files changed

+81
-6
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1010

1111
### Fixed
1212
* [`jsx-no-literals`]: properly error on children with noAttributeStrings: true ([#3317][] @TildaDares)
13+
* [`jsx-key`]: catch key errors inside conditional statements ([#3320][] @TildaDates)
1314

1415
### Changed
1516
* [Refactor] [`jsx-indent-props`]: improved readability of the checkNodesIndent function ([#3315][] @caroline223)
1617

18+
[#3320]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3320
1719
[#3317]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3317
1820
[#3315]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3315
1921
[#3311]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3311

lib/rules/jsx-key.js

+27-6
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,28 @@ module.exports = {
8686
}
8787
}
8888

89-
function getReturnStatement(body) {
90-
return body.filter((item) => item.type === 'ReturnStatement')[0];
89+
function getReturnStatements(node) {
90+
const returnStatements = arguments[1] || [];
91+
if (node.type === 'IfStatement') {
92+
if (node.consequent) {
93+
getReturnStatements(node.consequent, returnStatements);
94+
}
95+
if (node.alternate) {
96+
getReturnStatements(node.alternate, returnStatements);
97+
}
98+
} else {
99+
node.body.forEach((item) => {
100+
if (item.type === 'IfStatement') {
101+
getReturnStatements(item, returnStatements);
102+
}
103+
104+
if (item.type === 'ReturnStatement') {
105+
returnStatements.push(item);
106+
}
107+
});
108+
}
109+
110+
return returnStatements;
91111
}
92112

93113
function isKeyAfterSpread(attributes) {
@@ -189,10 +209,11 @@ module.exports = {
189209

190210
if (isFn || isArrFn) {
191211
if (fn.body.type === 'BlockStatement') {
192-
const returnStatement = getReturnStatement(fn.body.body);
193-
if (returnStatement && returnStatement.argument) {
194-
checkIteratorElement(returnStatement.argument);
195-
}
212+
getReturnStatements(fn.body)
213+
.filter((returnStatement) => returnStatement && returnStatement.argument)
214+
.forEach((returnStatement) => {
215+
checkIteratorElement(returnStatement.argument);
216+
});
196217
}
197218
}
198219
},

tests/lib/rules/jsx-key.js

+52
Original file line numberDiff line numberDiff line change
@@ -230,5 +230,57 @@ ruleTester.run('jsx-key', rule, {
230230
{ messageId: 'nonUniqueKeys', line: 5 },
231231
],
232232
},
233+
{
234+
code: `
235+
const Test = () => {
236+
const list = [1, 2, 3, 4, 5];
237+
238+
return (
239+
<div>
240+
{list.map(item => {
241+
if (item < 2) {
242+
return <div>{item}</div>;
243+
}
244+
245+
return <div />;
246+
})}
247+
</div>
248+
);
249+
};
250+
`,
251+
errors: [
252+
{ messageId: 'missingIterKey' },
253+
{ messageId: 'missingIterKey' },
254+
],
255+
},
256+
{
257+
code: `
258+
const TestO = () => {
259+
const list = [1, 2, 3, 4, 5];
260+
261+
return (
262+
<div>
263+
{list.map(item => {
264+
if (item < 2) {
265+
return <div>{item}</div>;
266+
} else if (item < 5) {
267+
return <div></div>
268+
} else {
269+
return <div></div>
270+
}
271+
272+
return <div />;
273+
})}
274+
</div>
275+
);
276+
};
277+
`,
278+
errors: [
279+
{ messageId: 'missingIterKey' },
280+
{ messageId: 'missingIterKey' },
281+
{ messageId: 'missingIterKey' },
282+
{ messageId: 'missingIterKey' },
283+
],
284+
},
233285
]),
234286
});

0 commit comments

Comments
 (0)