diff --git a/docs/rules/prefer-stateless-function.md b/docs/rules/prefer-stateless-function.md index 0eaf88d92a..d136f614c1 100644 --- a/docs/rules/prefer-stateless-function.md +++ b/docs/rules/prefer-stateless-function.md @@ -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. diff --git a/lib/rules/prefer-stateless-function.js b/lib/rules/prefer-stateless-function.js index 9cf896a616..4403273d9c 100644 --- a/lib/rules/prefer-stateless-function.js +++ b/lib/rules/prefer-stateless-function.js @@ -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` @@ -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; diff --git a/tests/lib/rules/prefer-stateless-function.js b/tests/lib/rules/prefer-stateless-function.js index 34e4601673..a7d8681728 100644 --- a/tests/lib/rules/prefer-stateless-function.js +++ b/tests/lib/rules/prefer-stateless-function.js @@ -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
{this.props.foo}
;', + ' }', + '}' + ].join('\n'), + parser: 'babel-eslint' + }, { + // Uses a called decorator + code: [ + '@foo("bar")', + 'class Foo extends React.Component {', + ' render() {', + ' return
{this.props.foo}
;', + ' }', + '}' + ].join('\n'), + parser: 'babel-eslint' + }, { + // Uses multiple decorators + code: [ + '@foo', + '@bar()', + 'class Foo extends React.Component {', + ' render() {', + ' return
{this.props.foo}
;', + ' }', + '}' + ].join('\n'), + parser: 'babel-eslint' } ],