From 74f99bec2712c5fdf637ff99d28068f055b901cf Mon Sep 17 00:00:00 2001 From: Tan Nguyen Date: Thu, 13 Sep 2018 13:54:38 +0700 Subject: [PATCH] [New] add `no-arrow-function-lifecycle` --- CHANGELOG.md | 1 + README.md | 1 + docs/rules/no-arrow-function-lifecycle.md | 41 + index.js | 1 + lib/rules/no-arrow-function-lifecycle.js | 55 ++ lib/rules/no-typos.js | 19 +- lib/util/lifecycleMethods.js | 25 + .../lib/rules/no-arrow-function-lifecycle.js | 729 ++++++++++++++++++ 8 files changed, 855 insertions(+), 17 deletions(-) create mode 100644 docs/rules/no-arrow-function-lifecycle.md create mode 100644 lib/rules/no-arrow-function-lifecycle.js create mode 100644 lib/util/lifecycleMethods.js create mode 100644 tests/lib/rules/no-arrow-function-lifecycle.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 79f0bfec7d..f939fe1442 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2754,3 +2754,4 @@ If you're still not using React 15 you can keep the old behavior by setting the [`static-property-placement`]: docs/rules/static-property-placement.md [`jsx-curly-newline`]: docs/rules/jsx-curly-newline.md [`jsx-no-useless-fragment`]: docs/rules/jsx-no-useless-fragment.md +[`no-arrow-function-lifecycle`]: docs/rules/no-arrow-function-lifecycle.md diff --git a/README.md b/README.md index 8629db136a..91bb95b2ee 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ Enable the rules that you would like to use. * [react/forbid-foreign-prop-types](docs/rules/forbid-foreign-prop-types.md): Forbid foreign propTypes * [react/no-access-state-in-setstate](docs/rules/no-access-state-in-setstate.md): Prevent using this.state inside this.setState * [react/no-array-index-key](docs/rules/no-array-index-key.md): Prevent using Array index in `key` props +* [react/no-arrow-function-lifecycle](docs/rules/no-arrow-function-lifecycle.md): Don't use arrow function for lifecycle methods * [react/no-children-prop](docs/rules/no-children-prop.md): Prevent passing children as props * [react/no-danger](docs/rules/no-danger.md): Prevent usage of dangerous JSX properties * [react/no-danger-with-children](docs/rules/no-danger-with-children.md): Prevent problem with children and props.dangerouslySetInnerHTML diff --git a/docs/rules/no-arrow-function-lifecycle.md b/docs/rules/no-arrow-function-lifecycle.md new file mode 100644 index 0000000000..96d6b5b891 --- /dev/null +++ b/docs/rules/no-arrow-function-lifecycle.md @@ -0,0 +1,41 @@ +# Lifecycle methods should be methods on the prototype, not class fields (react/no-arrow-function-lifecycle) + +It is not neccessary to use arrow function for lifecycle methods. This makes things harder to test, conceptually less performant (although in practice, performance will not be affected, since most engines will optimize efficiently), and can break hot reloading patterns. + +## Rule Details + +The following patterns are considered warnings: + +```jsx +class Hello extends React.Component { + render = () => { + return
; + } +} + +var AnotherHello = createReactClass({ + render: () => { + return
; + }, +}); +``` + +The following patterns are **not** considered warnings: + +```jsx +class Hello extends React.Component { + render() { + return
; + } +} + +var AnotherHello = createReactClass({ + render() { + return
; + }, +}); + +``` +## When Not To Use It + +If you don't care about performance of your application or conceptual correctness of class property placement, you can disable this rule. diff --git a/index.js b/index.js index c9511bb1e3..1cb0c4c099 100644 --- a/index.js +++ b/index.js @@ -52,6 +52,7 @@ const allRules = { 'jsx-wrap-multilines': require('./lib/rules/jsx-wrap-multilines'), 'no-access-state-in-setstate': require('./lib/rules/no-access-state-in-setstate'), 'no-array-index-key': require('./lib/rules/no-array-index-key'), + 'no-arrow-function-lifecycle': require('./lib/rules/no-arrow-function-lifecycle'), 'no-children-prop': require('./lib/rules/no-children-prop'), 'no-danger': require('./lib/rules/no-danger'), 'no-danger-with-children': require('./lib/rules/no-danger-with-children'), diff --git a/lib/rules/no-arrow-function-lifecycle.js b/lib/rules/no-arrow-function-lifecycle.js new file mode 100644 index 0000000000..2ca48afe87 --- /dev/null +++ b/lib/rules/no-arrow-function-lifecycle.js @@ -0,0 +1,55 @@ +/** + * @fileoverview Lifecycle methods should be methods on the prototype, not class fields + * @author Tan Nguyen + */ +'use strict'; + +const Components = require('../util/Components'); +const astUtil = require('../util/ast'); +const docsUrl = require('../util/docsUrl'); +const lifecycleMethods = require('../util/lifecycleMethods'); + +module.exports = { + meta: { + docs: { + description: 'Lifecycle methods should be methods on the prototype, not class fields', + category: 'Best Practices', + recommended: false, + url: docsUrl('no-arrow-function-lifecycle') + }, + schema: [] + }, + + create: Components.detect((context, components) => { + /** + * @param {Array} properties list of component properties + */ + function reportNoArrowFunctionLifecycle(properties) { + properties.forEach(node => { + const propertyName = astUtil.getPropertyName(node); + const nodeType = node.value && node.value.type; + const isLifecycleMethod = lifecycleMethods.indexOf(propertyName) !== -1; + + if (nodeType === 'ArrowFunctionExpression' && isLifecycleMethod) { + context.report({ + node, + message: '{{propertyName}} is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.', + data: { + propertyName + } + }); + } + }); + } + + return { + 'Program:exit': function() { + const list = components.list(); + Object.keys(list).forEach(component => { + const properties = astUtil.getComponentProperties(list[component].node); + reportNoArrowFunctionLifecycle(properties); + }); + } + }; + }) +}; diff --git a/lib/rules/no-typos.js b/lib/rules/no-typos.js index 3c943ad068..4df9ea8964 100644 --- a/lib/rules/no-typos.js +++ b/lib/rules/no-typos.js @@ -7,28 +7,13 @@ const PROP_TYPES = Object.keys(require('prop-types')); const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); +const lifecycleMethods = require('../util/lifecycleMethods'); // ------------------------------------------------------------------------------ // Rule Definition // ------------------------------------------------------------------------------ const STATIC_CLASS_PROPERTIES = ['propTypes', 'contextTypes', 'childContextTypes', 'defaultProps']; -const LIFECYCLE_METHODS = [ - 'getDerivedStateFromProps', - 'componentWillMount', - 'UNSAFE_componentWillMount', - 'componentDidMount', - 'componentWillReceiveProps', - 'UNSAFE_componentWillReceiveProps', - 'shouldComponentUpdate', - 'componentWillUpdate', - 'UNSAFE_componentWillUpdate', - 'getSnapshotBeforeUpdate', - 'componentDidUpdate', - 'componentDidCatch', - 'componentWillUnmount', - 'render' -]; module.exports = { meta: { @@ -143,7 +128,7 @@ module.exports = { } function reportErrorIfLifecycleMethodCasingTypo(node) { - LIFECYCLE_METHODS.forEach((method) => { + lifecycleMethods.forEach(method => { if (method.toLowerCase() === node.key.name.toLowerCase() && method !== node.key.name) { context.report({ node, diff --git a/lib/util/lifecycleMethods.js b/lib/util/lifecycleMethods.js new file mode 100644 index 0000000000..2fed165647 --- /dev/null +++ b/lib/util/lifecycleMethods.js @@ -0,0 +1,25 @@ +/** + * @fileoverview lifecycle methods + * @author Tan Nguyen + */ +'use strict'; + +module.exports = [ + 'getDefaultProps', + 'getInitialState', + 'getChildContext', + 'getDerivedStateFromProps', + 'componentWillMount', + 'UNSAFE_componentWillMount', + 'componentDidMount', + 'componentWillReceiveProps', + 'UNSAFE_componentWillReceiveProps', + 'shouldComponentUpdate', + 'componentWillUpdate', + 'UNSAFE_componentWillUpdate', + 'getSnapshotBeforeUpdate', + 'componentDidUpdate', + 'componentDidCatch', + 'componentWillUnmount', + 'render' +]; diff --git a/tests/lib/rules/no-arrow-function-lifecycle.js b/tests/lib/rules/no-arrow-function-lifecycle.js new file mode 100644 index 0000000000..3ef25f385c --- /dev/null +++ b/tests/lib/rules/no-arrow-function-lifecycle.js @@ -0,0 +1,729 @@ +/** + * @fileoverview It is not necessary to use arrow function for lifecycle methods + * @author Tan Nguyen + */ +'use strict'; + +const rule = require('../../../lib/rules/no-arrow-function-lifecycle'); +const RuleTester = require('eslint').RuleTester; + +require('babel-eslint'); + +const parserOptions = { + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + jsx: true + } +}; + +// ------------------------------------------------------------------------------ +// Tests +// ------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({parserOptions}); +ruleTester.run('no-arrow-function-lifecycle', rule, { + valid: [{ + code: ` + var Hello = createReactClass({ + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + getDefaultProps: function() { return {}; }, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + getInitialState: function() { return {}; }, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + getChildContext: function() { return {}; }, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + getDerivedStateFromProps: function() { return {}; }, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + componentWillMount: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + UNSAFE_componentWillMount: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + componentDidMount: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + componentWillReceiveProps: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + UNSAFE_componentWillReceiveProps: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + shouldComponentUpdate: function() { return true; }, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + componentWillUpdate: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + UNSAFE_componentWillUpdate: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + getSnapshotBeforeUpdate: function() { return {}; }, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + componentDidUpdate: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + componentDidCatch: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + componentWillUnmount: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + var Hello = createReactClass({ + componentWillUnmount: function() {}, + render: function() { return
; } + }); + ` + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getDefaultProps() { return {}; } + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getInitialState() { return {}; } + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getChildContext() { return {}; } + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getDerivedStateFromProps() { return {}; } + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentWillMount() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + UNSAFE_componentWillMount() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentDidMount() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentWillReceiveProps() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + UNSAFE_componentWillReceiveProps() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + shouldComponentUpdate() { return true; } + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentWillUpdate() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + UNSAFE_componentWillUpdate() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getSnapshotBeforeUpdate() { return {}; } + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentDidUpdate() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentDidCatch() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentWillUnmount() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentWillUnmount() {} + render() { return
; } + } + `, + parser: 'babel-eslint' + }], + + invalid: [{ + code: ` + var Hello = createReactClass({ + render: () => { return
; } + }); + `, + errors: [{ + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + getDefaultProps: () => { return {}; }, + render: function() { return
; } + }); + `, + errors: [{ + message: 'getDefaultProps is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + getInitialState: () => { return {}; }, + render: function() { return
; } + }); + `, + errors: [{ + message: 'getInitialState is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + getChildContext: () => { return {}; }, + render: function() { return
; } + }); + `, + errors: [{ + message: 'getChildContext is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + getDerivedStateFromProps: () => { return {}; }, + render: function() { return
; } + }); + `, + errors: [{ + message: 'getDerivedStateFromProps is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + componentWillMount: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'componentWillMount is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + UNSAFE_componentWillMount: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'UNSAFE_componentWillMount is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + componentDidMount: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'componentDidMount is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + componentWillReceiveProps: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'componentWillReceiveProps is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + UNSAFE_componentWillReceiveProps: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'UNSAFE_componentWillReceiveProps is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + shouldComponentUpdate: () => { return true; }, + render: function() { return
; } + }); + `, + errors: [{ + message: 'shouldComponentUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + componentWillUpdate: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'componentWillUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + UNSAFE_componentWillUpdate: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'UNSAFE_componentWillUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + getSnapshotBeforeUpdate: () => { return {}; }, + render: function() { return
; } + }); + `, + errors: [{ + message: 'getSnapshotBeforeUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + componentDidUpdate: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'componentDidUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + componentDidCatch: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'componentDidCatch is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + componentWillUnmount: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'componentWillUnmount is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + var Hello = createReactClass({ + componentWillUnmount: () => {}, + render: function() { return
; } + }); + `, + errors: [{ + message: 'componentWillUnmount is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getDefaultProps = () => { return {}; } + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'getDefaultProps is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getInitialState = () => { return {}; } + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'getInitialState is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getChildContext = () => { return {}; } + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'getChildContext is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getDerivedStateFromProps = () => { return {}; } + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'getDerivedStateFromProps is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentWillMount = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'componentWillMount is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + UNSAFE_componentWillMount = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'UNSAFE_componentWillMount is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentDidMount = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'componentDidMount is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentWillReceiveProps = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'componentWillReceiveProps is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + UNSAFE_componentWillReceiveProps = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'UNSAFE_componentWillReceiveProps is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + shouldComponentUpdate = () => { return true; } + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'shouldComponentUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentWillUpdate = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'componentWillUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + UNSAFE_componentWillUpdate = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'UNSAFE_componentWillUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + getSnapshotBeforeUpdate = () => { return {}; } + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'getSnapshotBeforeUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentDidUpdate = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'componentDidUpdate is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentDidCatch = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'componentDidCatch is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }, { + code: ` + class Hello extends React.Component { + handleEventMethods = () => {} + componentWillUnmount = () => {} + render = () => { return
; } + } + `, + parser: 'babel-eslint', + errors: [{ + message: 'componentWillUnmount is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }, { + message: 'render is a React lifecycle method, and should not be an arrow function. Use an instance method instead.' + }] + }] +});