Skip to content

Commit a925eea

Browse files
author
Simon Schick
committed
fixup! fixup! fixup! feat(rules): add jsx-props-no-spread-multi
1 parent 54ecbdc commit a925eea

File tree

6 files changed

+18
-11
lines changed

6 files changed

+18
-11
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ module.exports = [
338338
| [jsx-one-expression-per-line](docs/rules/jsx-one-expression-per-line.md) | Require one JSX element per line | | | 🔧 | | |
339339
| [jsx-pascal-case](docs/rules/jsx-pascal-case.md) | Enforce PascalCase for user-defined JSX components | | | | | |
340340
| [jsx-props-no-multi-spaces](docs/rules/jsx-props-no-multi-spaces.md) | Disallow multiple spaces between inline JSX props | | | 🔧 | | |
341-
| [jsx-props-no-spread-multi](docs/rules/jsx-props-no-spread-multi.md) | Disallow JSX prop spreading the same expression multiple times | ☑️ | | | | |
341+
| [jsx-props-no-spread-multi](docs/rules/jsx-props-no-spread-multi.md) | Disallow JSX prop spreading the same expression multiple times | | | | | |
342342
| [jsx-props-no-spreading](docs/rules/jsx-props-no-spreading.md) | Disallow JSX prop spreading | | | | | |
343343
| [jsx-sort-default-props](docs/rules/jsx-sort-default-props.md) | Enforce defaultProps declarations alphabetical sorting | | | | ||
344344
| [jsx-sort-props](docs/rules/jsx-sort-props.md) | Enforce props alphabetical sorting | | | 🔧 | | |

configs/recommended.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ module.exports = Object.assign({}, all, {
1111
'react/jsx-no-duplicate-props': 2,
1212
'react/jsx-no-target-blank': 2,
1313
'react/jsx-no-undef': 2,
14-
'react/jsx-props-no-spread-multi': 2,
1514
'react/jsx-uses-react': 2,
1615
'react/jsx-uses-vars': 2,
1716
'react/no-children-prop': 2,

docs/rules/jsx-props-no-spread-multi.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Disallow JSX prop spreading the same expression multiple times (`react/jsx-props-no-spread-multi`)
22

3-
💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).
4-
53
<!-- end auto-generated rule header -->
64

75
Enforces that any unique express is only spread once. Generally spreading the same expression twice is an indicator of a mistake since any attribute between the spreads may be overridden when

lib/rules/jsx-props-no-spread-multi.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,23 @@ const messages = {
1616
noMultiSpreading: 'Spreading the same expression multiple times is forbidden',
1717
};
1818

19+
const ignoredAstProperties = new Set(['parent', 'range', 'loc', 'start', 'end', '_babelType']);
20+
1921
/**
2022
* Filter for JSON.stringify that omits circular and position structures.
2123
*
2224
* @param {string} key
2325
* @param {*} value
2426
* @returns {*}
2527
*/
26-
const propertyFilter = (key, value) => (key !== 'parent' && key !== 'range' && key !== 'loc' ? value : undefined);
28+
const propertyFilter = (key, value) => (ignoredAstProperties.has(key) ? undefined : value);
2729

2830
module.exports = {
2931
meta: {
3032
docs: {
3133
description: 'Disallow JSX prop spreading the same expression multiple times',
3234
category: 'Best Practices',
33-
recommended: true,
35+
recommended: false,
3436
url: docsUrl('jsx-props-no-spread-multi'),
3537
},
3638
messages,
@@ -43,16 +45,17 @@ module.exports = {
4345
if (spreads.length < 2) {
4446
return;
4547
}
46-
const hashes = new Set();
48+
// We detect duplicate expressions by hashing the ast nodes
49+
const argumentHashes = new Set();
4750
for (const spread of spreads) {
4851
// TODO: Deep compare ast function?
49-
const hash = JSON.stringify(spread, propertyFilter);
50-
if (hashes.has(hash)) {
52+
const hash = JSON.stringify(spread.argument, propertyFilter);
53+
if (argumentHashes.has(hash)) {
5154
report(context, messages.noMultiSpreading, 'noMultiSpreading', {
5255
node: spread,
5356
});
5457
}
55-
hashes.add(hash);
58+
argumentHashes.add(hash);
5659
}
5760
},
5861
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"@typescript-eslint/parser": "^2.34.0 || ^3.10.1 || ^4.0.0 || ^5.0.0",
5858
"aud": "^2.0.4",
5959
"babel-eslint": "^8 || ^9 || ^10.1.0",
60-
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8",
60+
"eslint": "^3.19.0",
6161
"eslint-config-airbnb-base": "^15.0.0",
6262
"eslint-doc-generator": "^1.7.0",
6363
"eslint-plugin-eslint-plugin": "^2.3.0 || ^3.5.3 || ^4.0.1 || ^5.0.5",

tests/lib/rules/jsx-props-no-spread-multi.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ ruleTester.run('jsx-props-no-spread-multi', rule, {
6060
`,
6161
errors: [expectedError],
6262
},
63+
{
64+
code: `
65+
const props = {};
66+
<div {...props} {...props} {...props} />
67+
`,
68+
errors: [expectedError, expectedError],
69+
},
6370
{
6471
code: `
6572
const func = () => ({});

0 commit comments

Comments
 (0)