Skip to content

Commit 0c2aea0

Browse files
committed
react unsafe lifecycles
1 parent 66570a0 commit 0c2aea0

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# react#rename-unsafe-lifecycles
2+
3+
Adds `UNSAFE_` prefix for deprecated lifecycle hooks. (For more information about this codemod, see [React RFC #6](https://github.com/reactjs/rfcs/pull/6))
4+
5+
```js
6+
/* INPUT */
7+
class ExampleComponent extends React.Component {
8+
componentWillMount() { }
9+
componentWillUpdate(nextProps, nextState) { }
10+
componentWillReceiveProps(nextProps) { }
11+
}
12+
13+
/* OUTPUT */
14+
class ExampleComponent extends React.Component {
15+
UNSAFE_componentWillMount() { }
16+
UNSAFE_componentWillUpdate(nextProps, nextState) { }
17+
UNSAFE_componentWillReceiveProps(nextProps) { }
18+
}
19+
```
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { applyTransform } from '@codeshift/test-utils';
2+
import * as transformer from './transform';
3+
4+
describe('react#rename-unsafe-lifecycles transform', () => {
5+
it('should transform correctly', async () => {
6+
const result = await applyTransform(
7+
transformer,
8+
`
9+
class ExampleComponent extends React.Component {
10+
componentWillMount() { }
11+
componentWillUpdate(nextProps, nextState) { }
12+
componentWillReceiveProps(nextProps) { }
13+
}
14+
`,
15+
{ parser: 'tsx' },
16+
);
17+
18+
expect(result).toMatchInlineSnapshot(`
19+
"class ExampleComponent extends React.Component {
20+
UNSAFE_componentWillMount() { }
21+
UNSAFE_componentWillUpdate(nextProps, nextState) { }
22+
UNSAFE_componentWillReceiveProps(nextProps) { }
23+
}"
24+
`);
25+
});
26+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { API, FileInfo, Options } from 'jscodeshift';
2+
3+
const DEPRECATED_APIS = Object.create(null);
4+
DEPRECATED_APIS.componentWillMount = 'UNSAFE_componentWillMount';
5+
DEPRECATED_APIS.componentWillReceiveProps = 'UNSAFE_componentWillReceiveProps';
6+
DEPRECATED_APIS.componentWillUpdate = 'UNSAFE_componentWillUpdate';
7+
8+
export default function transformer(
9+
file: FileInfo,
10+
{ jscodeshift: j }: API,
11+
options: Options,
12+
) {
13+
const root = j(file.source);
14+
15+
let hasModifications = false;
16+
17+
const renameDeprecatedApis = (path: any) => {
18+
const name = path.node.key.name;
19+
20+
if (DEPRECATED_APIS[name]) {
21+
path.value.key.name = DEPRECATED_APIS[name];
22+
hasModifications = true;
23+
}
24+
};
25+
26+
const renameDeprecatedCallExpressions = (path: any) => {
27+
const name = path.node.property.name;
28+
29+
if (DEPRECATED_APIS[name]) {
30+
path.node.property.name = DEPRECATED_APIS[name];
31+
hasModifications = true;
32+
}
33+
};
34+
35+
// Class methods
36+
root.find(j.MethodDefinition).forEach(renameDeprecatedApis);
37+
38+
// Class methods - typescript
39+
root.find(j.ClassMethod).forEach(renameDeprecatedApis);
40+
41+
// Arrow functions
42+
root.find(j.ClassProperty).forEach(renameDeprecatedApis);
43+
44+
// createReactClass and mixins
45+
root.find(j.Property).forEach(renameDeprecatedApis);
46+
47+
// Function calls
48+
root.find(j.MemberExpression).forEach(renameDeprecatedCallExpressions);
49+
50+
return hasModifications ? root.toSource(options.printOptions) : null;
51+
}

0 commit comments

Comments
 (0)