Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore class properties in destructuring-assignment #1909

Merged
merged 1 commit into from Aug 5, 2018
Merged

Ignore class properties in destructuring-assignment #1909

merged 1 commit into from Aug 5, 2018

Conversation

alexandernanberg
Copy link
Contributor

Fixes #1875

Please let me know if you would like me to add more tests or if anything can be improved

@alexandernanberg alexandernanberg changed the title Ignore class properties in destructure-assignment Ignore class properties in destructuring-assignment Jul 30, 2018
Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be behind an option; the default behavior should be to warn inside class properties.

@alexandernanberg
Copy link
Contributor Author

Hmm not sure that I agree with you on that, because there is no way to "silence" the warning without refactor the code to use a constructor instead, which in my opinion is unnecessary.

But I'll update my PR accordingly!

@ljharb
Copy link
Member

ljharb commented Jul 30, 2018

That's one of the points of the rule - if you need to rely on props values, it's supposed to force it to go in the constructor.

@alexandernanberg
Copy link
Contributor Author

Okay I get it!

How would you like the option to be implemented? Not sure that I see a clear way to do it well without a breaking change. I guess we could add another enum option like ignoreClassProperties but I feel that it would maybe be a bit ambiguous?

@ljharb
Copy link
Member

ljharb commented Jul 30, 2018

allowInClassFields seems reasonable to me, or allow: ["class-fields"] (where that's the only allowed value atm)

@alexandernanberg
Copy link
Contributor Author

Okay so I've now added the option, I went for another name because I thought it was more logical than using the "allow" word, but let me know if you want me to change it. I also a bit unsure if I wrote the schema correctly

So you would do this;
["error", "always", { "ignoreClassFields": true }]

}]
},

create: Components.detect((context, components, utils) => {
const configuration = context.options[0] || DEFAULT_OPTION;

const ignoreClassFields = configuration === 'always' && context.options[1] && context.options[1].ignoreClassFields === true || false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when set to “never”, this should still apply - you could maybe have foo = function () { const { a } = this.props; }.call(this), or when do expressions land, you could have foo = do { const { a } = this.props; a; }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, I updated the PR so it should work with "never" as well 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep it probably should. Sorry for missing that, I've never worked in AST or eslint-plugin projects before so it's all new to me. I've updated the PR again.

@HenriBeck
Copy link

@ljharb should this be behind a flag because it doesn't have to do anything with destructuring assignments? I would agree that it would be a great rule to disallow props usage inside class properties but doing it here might be a little bit confusing for people.

@ljharb
Copy link
Member

ljharb commented Aug 2, 2018

@HenriBeck the rule is to force, or forbid, destructuring assignment regardless of location inside a class body. That class fields make destructuring awkward might be an inconvenience to some, hence the need for an option - but personally, I like the side effect that if you're trying to do anything complex in a class field, it forces you to properly put it in a constructor.

@HenriBeck
Copy link

@ljharb I agree with you that doing complicated things inside class properties isn't the best idea.
But forbidding it in this rule seems odd because class properties aren't about destructuring and should be able to disallow them whether or not you have this rule configured.

@ljharb
Copy link
Member

ljharb commented Aug 2, 2018

Methods aren't about destructuring either - the rule deals with any references to state, props, or context, no matter where they appear.

@alexandernanberg
Copy link
Contributor Author

alexandernanberg commented Aug 4, 2018

I think this should be ready to get merged unless there is anything else you want me to adjust?

@alexandernanberg
Copy link
Contributor Author

Well shit, this does not work when assigning an object with properties containing this.props to a class field.

class Foo extends React.Component {
  state = {
    // this will still throw an error
    bar: this.props.bar
  }
}

Did a quick try to fix this but didn't make any progress, can somebody either try to solve this or point me in the right direction? @ljharb

@techimist
Copy link

techimist commented Aug 24, 2018

Yup 7.11.1, the below still warns me about de-structuring props assignment:
const sampleSchemaData = this.props.schemaData

with the following rule in eslintrc:

"rules": {
    "react/destructuring-assignment": [1, "always", { "ignoreClassFields": true }]
}

@ljharb
Copy link
Member

ljharb commented Aug 24, 2018

@Anna93 that’s a variable, not a class field.

@zslabs
Copy link

zslabs commented Sep 13, 2018

This still throws one for me using the same setup as @Anna93:

class Input extends React.Component {
  id = `${this.props.name}-${generateUUID()}`;
 ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

6 participants