Skip to content

Commit

Permalink
prefer-stateless-function w/ decorators
Browse files Browse the repository at this point in the history
Currently prefer-stateless-function warns when using a decorated class
over a stateless function. The decorator syntax only works with classes,
so it makes sense not to warn in this case.

Fixes jsx-eslint#1034
  • Loading branch information
benstepp committed Feb 23, 2017
1 parent 8148833 commit 3266ab6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/rules/prefer-stateless-function.md
Expand Up @@ -10,6 +10,7 @@ This rule will check your class based React components for
* instance property other than `this.props` and `this.context`
* extension of `React.PureComponent` (if the `ignorePureComponents` flag is true)
* presence of `ref` attribute in JSX
* the use of decorators
* `render` method that return anything but JSX: `undefined`, `null`, etc. (only in React <15.0.0, see [shared settings](https://github.com/yannickcr/eslint-plugin-react/blob/master/README.md#configuration) for React version configuration)

If none of these elements are found, the rule will warn you to write this component as a pure function.
Expand Down
15 changes: 15 additions & 0 deletions lib/rules/prefer-stateless-function.js
Expand Up @@ -286,11 +286,25 @@ module.exports = {
});
}

/**
* Mark a ClassDeclaration as having used decorators
* @param {ASTNode} node The AST node being checked.
*/
function markDecoratorsAsUsed(node) {
components.set(node, {
useDecorators: true
});
}

return {
ClassDeclaration: function (node) {
if (ignorePureComponents && utils.isPureComponent(node)) {
markSCUAsDeclared(node);
}

if (node.decorators && node.decorators.length) {
markDecoratorsAsUsed(node);
}
},

// Mark `this` destructuring as a usage of `this`
Expand Down Expand Up @@ -378,6 +392,7 @@ module.exports = {
list[component].useRef ||
list[component].invalidReturn ||
list[component].hasChildContextTypes ||
list[component].useDecorators ||
(!utils.isES5Component(list[component].node) && !utils.isES6Component(list[component].node))
) {
continue;
Expand Down
34 changes: 34 additions & 0 deletions tests/lib/rules/prefer-stateless-function.js
Expand Up @@ -268,6 +268,40 @@ ruleTester.run('prefer-stateless-function', rule, {
'};'
].join('\n'),
parser: 'babel-eslint'
}, {
// Uses a decorator
code: [
'@foo',
'class Foo extends React.Component {',
' render() {',
' return <div>{this.props.foo}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint'
}, {
// Uses a called decorator
code: [
'@foo("bar")',
'class Foo extends React.Component {',
' render() {',
' return <div>{this.props.foo}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint'
}, {
// Uses multiple decorators
code: [
'@foo',
'@bar()',
'class Foo extends React.Component {',
' render() {',
' return <div>{this.props.foo}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint'
}
],

Expand Down

0 comments on commit 3266ab6

Please sign in to comment.