Skip to content

Commit

Permalink
[New] destructuring-assignment: add ignoreUseContext option
Browse files Browse the repository at this point in the history
  • Loading branch information
102 committed Jun 1, 2023
1 parent 747fad0 commit 0b83192
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
17 changes: 16 additions & 1 deletion docs/rules/destructuring-assignment.md
Expand Up @@ -96,7 +96,7 @@ const Foo = class extends React.PureComponent {

```js
...
"react/destructuring-assignment": [<enabled>, "always", { "ignoreClassFields": <boolean>, "destructureInSignature": "always" | "ignore" }]
"react/destructuring-assignment": [<enabled>, "always", { "ignoreClassFields": <boolean>, "destructureInSignature": "always" | "ignore", "ignoreUseContext": <boolean> }]
...
```

Expand Down Expand Up @@ -139,3 +139,18 @@ function Foo(props) {
return <Goo a={a}/>
}
```

### `ignoreUseContext`

When configured with `true`, the rule will ignore values returned from `useContext`.

Examples of **correct** code for this rule:

```jsx
import { useContext } from 'react';

function Foo() {
const foo = useContext(fooContext);
return <>{foo.bar}</>
}
```
8 changes: 6 additions & 2 deletions lib/rules/destructuring-assignment.js
Expand Up @@ -84,6 +84,9 @@ module.exports = {
'ignore',
],
},
ignoreUseContext: {
type: 'boolean',
},
},
additionalProperties: false,
}],
Expand All @@ -92,6 +95,7 @@ module.exports = {
create: Components.detect((context, components, utils) => {
const configuration = context.options[0] || DEFAULT_OPTION;
const ignoreClassFields = (context.options[1] && (context.options[1].ignoreClassFields === true)) || false;
const ignoreUseContext = (context.options[1] && (context.options[1].ignoreUseContext === true)) || false;
const destructureInSignature = (context.options[1] && context.options[1].destructureInSignature) || 'ignore';
const sfcParams = createSFCParams();

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

if (SFCComponent && destructuringUseContext && configuration === 'never') {
if (SFCComponent && destructuringUseContext && !ignoreUseContext && configuration === 'never') {
report(context, messages.noDestructAssignment, 'noDestructAssignment', {
node,
data: {
Expand Down
54 changes: 54 additions & 0 deletions tests/lib/rules/destructuring-assignment.js
Expand Up @@ -433,6 +433,30 @@ ruleTester.run('destructuring-assignment', rule, {
`,
features: ['optional chaining'],
},
{
code: `
import { useContext } from 'react';
const MyComponent = (props) => {
const foo = useContext(aContext);
return <div>{foo.test}</div>
};
`,
options: ['always', { ignoreUseContext: true }],
settings: { react: { version: '16.9.0' } },
},
{
code: `
import { useContext } from 'react';
const MyComponent = (props) => {
const {foo} = useContext(aContext);
return <div>{foo}</div>
};
`,
options: ['never', { ignoreUseContext: true }],
settings: { react: { version: '16.9.0' } },
},
]),

invalid: parsers.all([].concat(
Expand Down Expand Up @@ -890,6 +914,36 @@ ruleTester.run('destructuring-assignment', rule, {
errors: [
{ message: 'Must never use destructuring useContext assignment' },
],
},
{
code: `
import { useContext } from 'react';
const MyComponent = (props) => {
const foo = useContext(aContext);
return <div>{foo.test}</div>
};
`,
options: ['always', { ignoreUseContext: false }],
settings: { react: { version: '16.9.0' } },
errors: [
{ message: 'Must use destructuring foo assignment' },
],
},
{
code: `
import { useContext } from 'react';
const MyComponent = (props) => {
const {foo} = useContext(aContext);
return <div>{foo}</div>
};
`,
options: ['never', { ignoreUseContext: false }],
settings: { react: { version: '16.9.0' } },
errors: [
{ message: 'Must never use destructuring useContext assignment' },
],
}
)),
});

0 comments on commit 0b83192

Please sign in to comment.