Skip to content

Commit 2a25d59

Browse files
committed
[New] destructuring-assignment: add ignoreUseContext option
1 parent 693860f commit 2a25d59

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed

docs/rules/destructuring-assignment.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ const Foo = class extends React.PureComponent {
9696

9797
```js
9898
...
99-
"react/destructuring-assignment": [<enabled>, "always", { "ignoreClassFields": <boolean>, "destructureInSignature": "always" | "ignore" }]
99+
"react/destructuring-assignment": [<enabled>, "always", { "ignoreClassFields": <boolean>, "destructureInSignature": "always" | "ignore", "ignoreUseContext": <boolean> }]
100100
...
101101
```
102102

@@ -139,3 +139,18 @@ function Foo(props) {
139139
return <Goo a={a}/>
140140
}
141141
```
142+
143+
### `ignoreUseContext`
144+
145+
When configured with `true`, the rule will ignore values returned from `useContext`.
146+
147+
Examples of **correct** code for this rule:
148+
149+
```jsx
150+
import { useContext } from 'react';
151+
152+
function Foo() {
153+
const foo = useContext(fooContext);
154+
return <>{foo.bar}</>
155+
}
156+
```

lib/rules/destructuring-assignment.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ module.exports = {
8484
'ignore',
8585
],
8686
},
87+
ignoreUseContext: {
88+
type: 'boolean',
89+
},
8790
},
8891
additionalProperties: false,
8992
}],
@@ -92,6 +95,7 @@ module.exports = {
9295
create: Components.detect((context, components, utils) => {
9396
const configuration = context.options[0] || DEFAULT_OPTION;
9497
const ignoreClassFields = (context.options[1] && (context.options[1].ignoreClassFields === true)) || false;
98+
const ignoreUseContext = (context.options[1] && (context.options[1].ignoreUseContext === true)) || false;
9599
const destructureInSignature = (context.options[1] && context.options[1].destructureInSignature) || 'ignore';
96100
const sfcParams = createSFCParams();
97101

@@ -152,7 +156,7 @@ module.exports = {
152156
const optional = node.optional
153157
// the below is for the old typescript-eslint parser
154158
|| context.getSourceCode().getText(node).slice(node.object.range[1] - node.range[0], node.object.range[1] - node.range[0] + 1) === '?';
155-
if (isContextUsed && configuration === 'always' && !optional) {
159+
if (isContextUsed && configuration === 'always' && !ignoreUseContext && !optional) {
156160
report(context, messages.useDestructAssignment, 'useDestructAssignment', {
157161
node,
158162
data: {
@@ -247,7 +251,7 @@ module.exports = {
247251
contextSet.add(node.id.name);
248252
}
249253

250-
if (SFCComponent && destructuringUseContext && configuration === 'never') {
254+
if (SFCComponent && destructuringUseContext && !ignoreUseContext && configuration === 'never') {
251255
report(context, messages.noDestructAssignment, 'noDestructAssignment', {
252256
node,
253257
data: {

tests/lib/rules/destructuring-assignment.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,30 @@ ruleTester.run('destructuring-assignment', rule, {
433433
`,
434434
features: ['optional chaining'],
435435
},
436+
{
437+
code: `
438+
import { useContext } from 'react';
439+
440+
const MyComponent = (props) => {
441+
const foo = useContext(aContext);
442+
return <div>{foo.test}</div>
443+
};
444+
`,
445+
options: ['always', { ignoreUseContext: true }],
446+
settings: { react: { version: '16.9.0' } },
447+
},
448+
{
449+
code: `
450+
import { useContext } from 'react';
451+
452+
const MyComponent = (props) => {
453+
const {foo} = useContext(aContext);
454+
return <div>{foo}</div>
455+
};
456+
`,
457+
options: ['never', { ignoreUseContext: true }],
458+
settings: { react: { version: '16.9.0' } },
459+
},
436460
]),
437461

438462
invalid: parsers.all([].concat(
@@ -890,6 +914,36 @@ ruleTester.run('destructuring-assignment', rule, {
890914
errors: [
891915
{ message: 'Must never use destructuring useContext assignment' },
892916
],
917+
},
918+
{
919+
code: `
920+
import { useContext } from 'react';
921+
922+
const MyComponent = (props) => {
923+
const foo = useContext(aContext);
924+
return <div>{foo.test}</div>
925+
};
926+
`,
927+
options: ['always', { ignoreUseContext: false }],
928+
settings: { react: { version: '16.9.0' } },
929+
errors: [
930+
{ message: 'Must use destructuring foo assignment' },
931+
],
932+
},
933+
{
934+
code: `
935+
import { useContext } from 'react';
936+
937+
const MyComponent = (props) => {
938+
const {foo} = useContext(aContext);
939+
return <div>{foo}</div>
940+
};
941+
`,
942+
options: ['never', { ignoreUseContext: false }],
943+
settings: { react: { version: '16.9.0' } },
944+
errors: [
945+
{ message: 'Must never use destructuring useContext assignment' },
946+
],
893947
}
894948
)),
895949
});

0 commit comments

Comments
 (0)