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

Add new rule for preventing this in SFCs #1509

Merged
merged 4 commits into from
Dec 1, 2017

Conversation

jomasti
Copy link
Contributor

@jomasti jomasti commented Oct 31, 2017

This rule will report errors when a stateless functional component is
attempting to use this.

This attempts to address the request in #1435.

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 probably be more generic, and forbid this in SFCs at all - this.state and this.context included.

How about no-this-in-sfc?

@jomasti
Copy link
Contributor Author

jomasti commented Oct 31, 2017

Okay, I can update the rule to report any usage of this. You mean all usages of this beyond just the typical React usages?

@ljharb
Copy link
Member

ljharb commented Oct 31, 2017

Yes; an SFC has no reason to use this at all

@jomasti jomasti changed the title Add new rule for preventing this.props in SFCs Add new rule for preventing this in SFCs Oct 31, 2017
@jomasti
Copy link
Contributor Author

jomasti commented Oct 31, 2017

Updated

ruleTester.run('no-this-in-sfc', rule, {
valid: [{
code: `
function Foo(props) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, this is really a nit :) don't these template literals need an extra indentation?

code: `
  mystring...
`,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the need is up to personal preference. I can change it if that is the standard preference.

Copy link
Member

Choose a reason for hiding this comment

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

imo the indentation of test cases in a non-indentation rule isn't that important, as long as it's readable.

return false;
}
property = 'argument';
}
Copy link
Contributor

@jseminck jseminck Nov 1, 2017

Choose a reason for hiding this comment

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

Is this code really needed?

no-typos rule also detects SFCs, it does it like so: ( stripped down, the original code is at: https://github.com/yannickcr/eslint-plugin-react/blob/master/lib/rules/no-typos.js#L137 )

      MemberExpression: function(node) {
        const relatedComponent = utils.getRelatedComponent(node);
        if (
          relatedComponent && utils.isReturningJSX(relatedComponent.node)
        ) {
          // Should be an SFC at this point
        }

There must be other places where SFC detection also exists.

On the other hand, perhaps this is a better approach, I don't know too much about the internals there...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, when I was calling getParentStatelessComponent before the change, it was returning any parent function, which is not what I wanted. So, I updated the function to check that the function is also returning JSX. When I did that with the previous version of isReturningJSX, it would fail on an ArrowFunctionExpression with a body. This caused several tests to fail. After I updated this case to check for the body, it resolved the failures. There may be multiple rules that do that sort of check, but I would prefer the logic to be in one place.

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.

LGTM overall, just some minor comments

}
```

The following patterns are **not** considered warnings:
Copy link
Member

Choose a reason for hiding this comment

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

let's also add non-warning patterns (and test cases) for destructured props/context

},

create: Components.detect((context, components, utils) => ({
MemberExpression: function(node) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: MemberExpression(node) {

@@ -442,7 +449,7 @@ function componentRule(rule, context) {
return null;
}
// Return the node if it is a function that is not a class method and is not inside a JSX Element
if (isFunction && !isMethod && !isJSXExpressionContainer) {
if (isFunction && !isMethod && !isJSXExpressionContainer && utils.isReturningJSX(node)) {
Copy link
Member

Choose a reason for hiding this comment

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

does isReturningJSX return true when something returns null?

Also, in React 16, components can return strings or arrays, so I'm not sure this detection will be reliable moving forward.

"React 16 fragments" will probably be something we have to solve in a separate PR anyways tho, so no need to address that now (i filed #1510)

@jseminck
Copy link
Contributor

jseminck commented Dec 1, 2017

Is there anything stopping from getting this merged? Just ran into an issue with this, using this.props in SFC by accident that caused a bug. Would be cool if linter catches it.

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.

3 participants