diff --git a/docs/rules/jsx-key.md b/docs/rules/jsx-key.md
index 0426f9f81a..250466eef0 100644
--- a/docs/rules/jsx-key.md
+++ b/docs/rules/jsx-key.md
@@ -27,6 +27,11 @@ Array.from([1, 2, 3], (x) => {x});
```
+```jsx
+arr = [];
+arr.push();
+```
+
In the last example the key is being spread, which is currently possible, but discouraged in favor of the statically provided key.
Examples of **correct** code for this rule:
@@ -47,6 +52,11 @@ Array.from([1, 2, 3], (x) => {x});
```
+```jsx
+arr = [];
+arr.push();
+```
+
## Rule Options
```js
diff --git a/lib/rules/jsx-key.js b/lib/rules/jsx-key.js
index 825d21f4bb..e49532665a 100644
--- a/lib/rules/jsx-key.js
+++ b/lib/rules/jsx-key.js
@@ -263,6 +263,22 @@ module.exports = {
}
},
+ // eslint-disable-next-line no-multi-str
+ 'CallExpression[callee.type="MemberExpression"][callee.property.name=/^push|unshift|splice|with|concat$/],\
+ CallExpression[callee.type="OptionalMemberExpression"][callee.property.name=/^push|unshift|splice|with|concat$/],\
+ OptionalCallExpression[callee.type="MemberExpression"][callee.property.name=/^push|unshift|splice|with|concat$/],\
+ OptionalCallExpression[callee.type="OptionalMemberExpression"][callee.property.name=/^push|unshift|splice|with|concat$/]'(node) {
+ node.arguments.forEach((arg) => {
+ if (arg.type === 'JSXElement' && !hasProp(arg.openingElement.attributes, 'key')) {
+ report(context, messages.missingIterKey, 'missingArrayKey', { node });
+ return;
+ }
+ if (arg.type === 'JSXFragment') {
+ report(context, messages.missingIterKey, 'missingArrayKeyUsePrag', { node });
+ }
+ });
+ },
+
// Array.prototype.map
// eslint-disable-next-line no-multi-str
'CallExpression[callee.type="MemberExpression"][callee.property.name="map"],\
diff --git a/tests/lib/rules/jsx-key.js b/tests/lib/rules/jsx-key.js
index 2c5ba7a5c1..3b94b08c3f 100644
--- a/tests/lib/rules/jsx-key.js
+++ b/tests/lib/rules/jsx-key.js
@@ -205,6 +205,12 @@ ruleTester.run('jsx-key', rule, {
`,
settings,
},
+ {
+ code: 'arr.push();',
+ },
+ {
+ code: 'arr.push();',
+ },
]),
invalid: parsers.all([
{
@@ -424,5 +430,13 @@ ruleTester.run('jsx-key', rule, {
options: [{ checkKeyMustBeforeSpread: true }],
errors: [{ messageId: 'keyBeforeSpread' }],
},
+ {
+ code: 'arr.push();',
+ errors: [{ messageId: 'missingArrayKey' }],
+ },
+ {
+ code: 'arr.push(<>>);',
+ errors: [{ messageId: 'missingArrayKeyUsePrag' }],
+ },
]),
});