Skip to content

Commit d68ef96

Browse files
authored
Merge pull request jsx-eslint#1750 from sergei-startsev/no-deprecated
[New] Adjusted no-deprecated rule for React 16.3.0
2 parents 8973758 + 7034ffc commit d68ef96

File tree

4 files changed

+420
-151
lines changed

4 files changed

+420
-151
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ Enable the rules that you would like to use.
102102
* [react/no-children-prop](docs/rules/no-children-prop.md): Prevent passing children as props
103103
* [react/no-danger](docs/rules/no-danger.md): Prevent usage of dangerous JSX properties
104104
* [react/no-danger-with-children](docs/rules/no-danger-with-children.md): Prevent problem with children and props.dangerouslySetInnerHTML
105-
* [react/no-deprecated](docs/rules/no-deprecated.md): Prevent usage of deprecated methods
105+
* [react/no-deprecated](docs/rules/no-deprecated.md): Prevent usage of deprecated methods, including component lifecyle methods
106106
* [react/no-did-mount-set-state](docs/rules/no-did-mount-set-state.md): Prevent usage of `setState` in `componentDidMount`
107107
* [react/no-did-update-set-state](docs/rules/no-did-update-set-state.md): Prevent usage of `setState` in `componentDidUpdate`
108108
* [react/no-direct-mutation-state](docs/rules/no-direct-mutation-state.md): Prevent direct mutation of `this.state`

docs/rules/no-deprecated.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,27 @@ const propTypes = {
2727
React.DOM.div();
2828

2929
import React, { PropTypes } from 'react';
30+
31+
class Foo extends React.Component {
32+
componentWillMount() { }
33+
componentWillReceiveProps() { }
34+
componentWillUpdate() { }
35+
// ...
36+
}
37+
38+
class Foo extends React.PureComponent {
39+
componentWillMount() { }
40+
componentWillReceiveProps() { }
41+
componentWillUpdate() { }
42+
// ...
43+
}
44+
45+
var Foo = createReactClass({
46+
componentWillMount: function() {},
47+
componentWillReceiveProps: function() {},
48+
componentWillUpdate: function() {},
49+
// ...
50+
})
3051
```
3152

3253
The following patterns are **not** considered warnings:
@@ -38,4 +59,10 @@ ReactDOM.render(<MyComponent />, root);
3859
ReactDOM.findDOMNode(this.refs.foo);
3960

4061
import { PropTypes } from 'prop-types';
62+
63+
class Foo {
64+
componentWillMount() { }
65+
componentWillReceiveProps() { }
66+
componentWillUpdate() { }
67+
}
4168
```

lib/rules/no-deprecated.js

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
* @fileoverview Prevent usage of deprecated methods
33
* @author Yannick Croissant
44
* @author Scott Feeney
5+
* @author Sergei Startsev
56
*/
67
'use strict';
78

89
const has = require('has');
910

11+
const Components = require('../util/Components');
12+
const astUtil = require('../util/ast');
13+
const docsUrl = require('../util/docsUrl');
1014
const pragmaUtil = require('../util/pragma');
1115
const versionUtil = require('../util/version');
12-
const docsUrl = require('../util/docsUrl');
1316

1417
// ------------------------------------------------------------------------------
1518
// Constants
@@ -20,7 +23,7 @@ const MODULES = {
2023
'react-addons-perf': ['ReactPerf', 'Perf']
2124
};
2225

23-
const DEPRECATED_MESSAGE = '{{oldMethod}} is deprecated since React {{version}}{{newMethod}}';
26+
const DEPRECATED_MESSAGE = '{{oldMethod}} is deprecated since React {{version}}{{newMethod}}{{refs}}';
2427

2528
// ------------------------------------------------------------------------------
2629
// Rule Definition
@@ -37,7 +40,7 @@ module.exports = {
3740
schema: []
3841
},
3942

40-
create: function(context) {
43+
create: Components.detect((context, components, utils) => {
4144
const sourceCode = context.getSourceCode();
4245
const pragma = pragmaUtil.getFromContext(context);
4346

@@ -73,6 +76,22 @@ module.exports = {
7376
deprecated[`${pragma}.PropTypes`] = ['15.5.0', 'the npm module prop-types'];
7477
// 15.6.0
7578
deprecated[`${pragma}.DOM`] = ['15.6.0', 'the npm module react-dom-factories'];
79+
// 16.3.0
80+
deprecated.componentWillMount = [
81+
'16.3.0',
82+
'UNSAFE_componentWillMount',
83+
'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount'
84+
];
85+
deprecated.componentWillReceiveProps = [
86+
'16.3.0',
87+
'UNSAFE_componentWillReceiveProps',
88+
'https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops'
89+
];
90+
deprecated.componentWillUpdate = [
91+
'16.3.0',
92+
'UNSAFE_componentWillUpdate',
93+
'https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate'
94+
];
7695
return deprecated;
7796
}
7897

@@ -91,13 +110,17 @@ module.exports = {
91110
return;
92111
}
93112
const deprecated = getDeprecated();
113+
const version = deprecated[method][0];
114+
const newMethod = deprecated[method][1];
115+
const refs = deprecated[method][2];
94116
context.report({
95117
node: node,
96118
message: DEPRECATED_MESSAGE,
97119
data: {
98120
oldMethod: method,
99-
version: deprecated[method][0],
100-
newMethod: deprecated[method][1] ? `, use ${deprecated[method][1]} instead` : ''
121+
version,
122+
newMethod: newMethod ? `, use ${newMethod} instead` : '',
123+
refs: refs ? `, see ${refs}` : ''
101124
}
102125
});
103126
}
@@ -119,6 +142,27 @@ module.exports = {
119142
return moduleName;
120143
}
121144

145+
/**
146+
* Returns life cycle methods if available
147+
* @param {ASTNode} node The AST node being checked.
148+
* @returns {Array} The array of methods.
149+
*/
150+
function getLifeCycleMethods(node) {
151+
const properties = astUtil.getComponentProperties(node);
152+
return properties.map(property => astUtil.getPropertyName(property));
153+
}
154+
155+
/**
156+
* Checks life cycle methods
157+
* @param {ASTNode} node The AST node being checked.
158+
*/
159+
function checkLifeCycleMethods(node) {
160+
if (utils.isES5Component(node) || utils.isES6Component(node)) {
161+
const methods = getLifeCycleMethods(node);
162+
methods.forEach(method => checkDeprecation(node, method));
163+
}
164+
}
165+
122166
// --------------------------------------------------------------------------
123167
// Public
124168
// --------------------------------------------------------------------------
@@ -145,10 +189,10 @@ module.exports = {
145189
VariableDeclarator: function(node) {
146190
const reactModuleName = getReactModuleName(node);
147191
const isRequire = node.init && node.init.callee && node.init.callee.name === 'require';
148-
const isReactRequire =
149-
node.init && node.init.arguments &&
150-
node.init.arguments.length && typeof MODULES[node.init.arguments[0].value] !== 'undefined'
151-
;
192+
const isReactRequire = node.init
193+
&& node.init.arguments
194+
&& node.init.arguments.length
195+
&& typeof MODULES[node.init.arguments[0].value] !== 'undefined';
152196
const isDestructuring = node.id && node.id.type === 'ObjectPattern';
153197

154198
if (
@@ -160,8 +204,11 @@ module.exports = {
160204
node.id.properties.forEach(property => {
161205
checkDeprecation(node, `${reactModuleName || pragma}.${property.key.name}`);
162206
});
163-
}
207+
},
164208

209+
ClassDeclaration: checkLifeCycleMethods,
210+
ClassExpression: checkLifeCycleMethods,
211+
ObjectExpression: checkLifeCycleMethods
165212
};
166-
}
213+
})
167214
};

0 commit comments

Comments
 (0)