Skip to content

Commit f5aeced

Browse files
Adjust no-unsafe rule to handle all unsafe life-cycle methods
- Adjust `no-unsafe` rule to handle all unsafe life-cycle methods including their aliases. - Add instructions on updating components to be consistent with React runtime warnings.
1 parent 376f5c2 commit f5aeced

File tree

4 files changed

+217
-21
lines changed

4 files changed

+217
-21
lines changed

README.md

Lines changed: 2 additions & 2 deletions
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`
@@ -117,7 +117,7 @@ Enable the rules that you would like to use.
117117
* [react/no-this-in-sfc](docs/rules/no-this-in-sfc.md): Prevent using `this` in stateless functional components
118118
* [react/no-unescaped-entities](docs/rules/no-unescaped-entities.md): Prevent invalid characters from appearing in markup
119119
* [react/no-unknown-property](docs/rules/no-unknown-property.md): Prevent usage of unknown DOM property (fixable)
120-
* [react/no-unsafe](docs/rules/no-unsafe.md): Prevent usage of `UNSAFE_` methods
120+
* [react/no-unsafe](docs/rules/no-unsafe.md): Prevent usage of unsafe lifecycle methods
121121
* [react/no-unused-prop-types](docs/rules/no-unused-prop-types.md): Prevent definitions of unused prop types
122122
* [react/no-unused-state](docs/rules/no-unused-state.md): Prevent definitions of unused state properties
123123
* [react/no-will-update-set-state](docs/rules/no-will-update-set-state.md): Prevent usage of `setState` in `componentWillUpdate`

docs/rules/no-unsafe.md

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
1-
# Prevent usage of `UNSAFE_` methods (react/no-unsafe)
1+
# Prevent usage of unsafe lifecycle methods (react/no-unsafe)
22

33
Certain legacy lifecycle methods are [unsafe for use in async React applications][async_rendering] and cause warnings in [_strict mode_][strict_mode]. These also happen to be the lifecycles that cause the most [confusion within the React community][component_lifecycle_changes].
44

55
[async_rendering]: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html
66
[strict_mode]: https://reactjs.org/docs/strict-mode.html#identifying-unsafe-lifecycles
77
[component_lifecycle_changes]: https://reactjs.org/blog/2018/03/29/react-v-16-3.html#component-lifecycle-changes
88

9-
The rule checks the following methods: `UNSAFE_componentWillMount`, `UNSAFE_componentWillReceiveProps`, `UNSAFE_componentWillUpdate`.
9+
The rule checks the following methods:
10+
- `componentWillMount` (and `UNSAFE_componentWillMount` alias)
11+
- `componentWillReceiveProps` (and `UNSAFE_componentWillReceiveProps` alias)
12+
- `componentWillUpdate` (and `UNSAFE_componentWillUpdate` alias)
1013

1114
## Rule Details
1215

1316
The following patterns are considered warnings:
1417

1518
```jsx
19+
class Foo extends React.Component {
20+
componentWillMount() {}
21+
componentWillReceiveProps() {}
22+
componentWillUpdate() {}
23+
}
24+
// or
1625
class Foo extends React.Component {
1726
UNSAFE_componentWillMount() {}
1827
UNSAFE_componentWillReceiveProps() {}
@@ -21,6 +30,12 @@ class Foo extends React.Component {
2130
```
2231

2332
```jsx
33+
const Foo = createReactClass({
34+
componentWillMount: function() {},
35+
componentWillReceiveProps: function() {},
36+
componentWillUpdate: function() {}
37+
});
38+
// or
2439
const Foo = createReactClass({
2540
UNSAFE_componentWillMount: function() {},
2641
UNSAFE_componentWillReceiveProps: function() {},
@@ -31,6 +46,12 @@ const Foo = createReactClass({
3146
The following patterns are **not** considered warnings:
3247

3348
```jsx
49+
class Foo extends Bar {
50+
componentWillMount() {}
51+
componentWillReceiveProps() {}
52+
componentWillUpdate() {}
53+
}
54+
// or
3455
class Foo extends Bar {
3556
UNSAFE_componentWillMount() {}
3657
UNSAFE_componentWillReceiveProps() {}
@@ -39,6 +60,12 @@ class Foo extends Bar {
3960
```
4061

4162
```jsx
63+
const Foo = bar({
64+
componentWillMount: function() {},
65+
componentWillReceiveProps: function() {},
66+
componentWillUpdate: function() {}
67+
});
68+
// or
4269
const Foo = bar({
4370
UNSAFE_componentWillMount: function() {},
4471
UNSAFE_componentWillReceiveProps: function() {},

lib/rules/no-unsafe.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* @fileoverview Prevent usage of UNSAFE_ methods
2+
* @fileoverview Prevent usage of unsafe lifecycle methods
33
* @author Sergei Startsev
44
*/
55

@@ -17,7 +17,7 @@ const versionUtil = require('../util/version');
1717
module.exports = {
1818
meta: {
1919
docs: {
20-
description: 'Prevent usage of UNSAFE_ methods',
20+
description: 'Prevent usage of unsafe lifecycle methods',
2121
category: 'Best Practices',
2222
recommended: false,
2323
url: docsUrl('no-unsafe')
@@ -31,16 +31,29 @@ module.exports = {
3131
return {};
3232
}
3333

34+
const unsafe = {};
35+
unsafe.componentWillMount = unsafe.UNSAFE_componentWillMount = {
36+
newMethod: 'componentDidMount',
37+
details:
38+
'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.'
39+
};
40+
unsafe.componentWillReceiveProps = unsafe.UNSAFE_componentWillReceiveProps = {
41+
newMethod: 'getDerivedStateFromProps',
42+
details:
43+
'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.'
44+
};
45+
unsafe.componentWillUpdate = unsafe.UNSAFE_componentWillUpdate = {
46+
newMethod: 'componentDidUpdate',
47+
details:
48+
'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.'
49+
};
50+
3451
/**
3552
* Returns a list of unsafe methods
3653
* @returns {Array} A list of unsafe methods
3754
*/
3855
function getUnsafeMethods() {
39-
return [
40-
'UNSAFE_componentWillMount',
41-
'UNSAFE_componentWillReceiveProps',
42-
'UNSAFE_componentWillUpdate'
43-
];
56+
return Object.keys(unsafe);
4457
}
4558

4659
/**
@@ -63,9 +76,13 @@ module.exports = {
6376
return;
6477
}
6578

79+
const meta = unsafe[method];
80+
const newMethod = meta.newMethod;
81+
const details = meta.details;
82+
6683
context.report({
6784
node: node,
68-
message: `${method} is unsafe for use in async rendering, see https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html`
85+
message: `${method} is unsafe for use in async rendering. Update the component to use ${newMethod} instead. ${details}`
6986
});
7087
}
7188

0 commit comments

Comments
 (0)