Skip to content

Commit 20aafc3

Browse files
author
Keyan Zhang
committed
changed to update the existing one instead
1 parent a151336 commit 20aafc3

14 files changed

+254
-1163
lines changed

README.md

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -100,52 +100,6 @@ guide](https://github.com/airbnb/javascript/blob/7684892951ef663e1c4e62ad57d662e
100100
jscodeshift -t react-codemod/transforms/sort-comp.js <path>
101101
```
102102

103-
### Explanation of the ES2015 class transform
104-
105-
* Ignore components with calls to deprecated APIs. This is very defensive, if
106-
the script finds any identifiers called `isMounted`, `getDOMNode`,
107-
`replaceProps`, `replaceState` or `setProps` it will skip the component.
108-
* Replaces `var A = React.createClass(spec)` with
109-
`class A (extends React.Component) {spec}`.
110-
* Pulls out all statics defined on `statics` plus the few special cased
111-
statics like `propTypes`, `childContextTypes`, `contextTypes` and
112-
`displayName` and assigns them after the class is created.
113-
`class A {}; A.foo = bar;`
114-
* Takes `getDefaultProps` and inlines it as a static `defaultProps`.
115-
If `getDefaultProps` is defined as a function with a single statement that
116-
returns an object, it optimizes and transforms
117-
`getDefaultProps() { return {foo: 'bar'}; }` into
118-
`A.defaultProps = {foo: 'bar'};`. If `getDefaultProps` contains more than
119-
one statement it will transform into a self-invoking function like this:
120-
`A.defaultProps = function() {…}();`. Note that this means that the function
121-
will be executed only a single time per app-lifetime. In practice this
122-
hasn't caused any issues – `getDefaultProps` should not contain any
123-
side-effects.
124-
* Binds class methods to the instance if methods are referenced without being
125-
called directly. It checks for `this.foo` but also traces variable
126-
assignments like `var self = this; self.foo`. It does not bind functions
127-
from the React API and ignores functions that are being called directly
128-
(unless it is both called directly and passed around to somewhere else)
129-
* Creates a constructor if necessary. This is necessary if either
130-
`getInitialState` exists in the `React.createClass` spec OR if functions
131-
need to be bound to the instance.
132-
* When `--no-super-class` is passed it only optionally extends
133-
`React.Component` when `setState` or `forceUpdate` are used within the
134-
class.
135-
136-
The constructor logic is as follows:
137-
138-
* Call `super(props, context)` if the base class needs to be extended.
139-
* Bind all functions that are passed around,
140-
like `this.foo = this.foo.bind(this)`
141-
* Inline `getInitialState` (and remove `getInitialState` from the spec). It
142-
also updates access of `this.props.foo` to `props.foo` and adds `props` as
143-
argument to the constructor. This is necessary in the case when the base
144-
class does not need to be extended where `this.props` will only be set by
145-
React after the constructor has been run.
146-
* Changes `return StateObject` from `getInitialState` to assign `this.state`
147-
directly.
148-
149103
### Explanation of the new ES2015 class transform with property initializers
150104

151105
* Ignore components with calls to deprecated APIs. This is very defensive, if

transforms/__testfixtures__/class-test2.js

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,78 @@
11
'use strict';
22

33
var React = require('React');
4+
var ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');
5+
var FooBarMixin = require('FooBarMixin');
6+
7+
class ComponentWithNonSimpleInitialState extends React.Component {
8+
static iDontKnowWhyYouNeedThis = true; // but comment it
9+
static foo = 'bar';
410

5-
// Comment
6-
module.exports = class extends React.Component {
711
constructor(props, context) {
812
super(props, context);
913

1014
this.state = {
11-
foo: 'bar',
15+
counter: props.initialNumber + 1,
1216
};
1317
}
1418

19+
render() {
20+
return (
21+
<div>{this.state.counter}</div>
22+
);
23+
}
24+
}
25+
26+
// Comment
27+
module.exports = class extends React.Component {
28+
static propTypes = {
29+
foo: React.PropTypes.bool,
30+
};
31+
32+
static defaultProps = {
33+
foo: 12,
34+
};
35+
36+
state = function() { // non-simple
37+
var data = 'bar';
38+
return {
39+
bar: data,
40+
};
41+
}();
42+
1543
render() {
1644
return <div />;
1745
}
1846
};
1947

20-
module.exports.propTypes = {
21-
foo: React.PropTypes.bool,
22-
};
48+
class ComponentWithOnlyPureRenderMixin extends React.PureComponent {
49+
constructor(props, context) {
50+
super(props, context);
51+
52+
this.state = {
53+
counter: props.initialNumber + 1,
54+
};
55+
}
56+
57+
render() {
58+
return (
59+
<div>{this.state.counter}</div>
60+
);
61+
}
62+
}
63+
64+
var ComponentWithInconvertibleMixins = React.createClass({
65+
mixins: [ReactComponentWithPureRenderMixin, FooBarMixin],
66+
67+
getInitialState: function() {
68+
return {
69+
counter: this.props.initialNumber + 1,
70+
};
71+
},
72+
73+
render: function() {
74+
return (
75+
<div>{this.state.counter}</div>
76+
);
77+
},
78+
});

transforms/__testfixtures__/class.input.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ var MyComponent = React.createClass({
1616
};
1717
},
1818

19-
foo: function() {
19+
foo: function(): void {
2020
this.setState({heyoo: 24});
2121
},
2222
});
@@ -26,7 +26,7 @@ var MyComponent2 = React.createClass({
2626
getDefaultProps: function() {
2727
return {a: 1};
2828
},
29-
foo: function() {
29+
foo: function() { // flow annotations dont work for now
3030
pass(this.foo);
3131
this.forceUpdate();
3232
},
@@ -35,7 +35,7 @@ var MyComponent2 = React.createClass({
3535
var MyComponent3 = React.createClass({
3636
statics: {
3737
someThing: 10,
38-
foo: function() {},
38+
funcThatDoesNothing: function(): void {},
3939
},
4040
propTypes: {
4141
highlightEntities: React.PropTypes.bool,
@@ -47,7 +47,7 @@ var MyComponent3 = React.createClass({
4747
},
4848

4949
getDefaultProps: function() {
50-
foo();
50+
unboundFunc();
5151
return {
5252
linkifyEntities: true,
5353
highlightEntities: false,
@@ -61,11 +61,11 @@ var MyComponent3 = React.createClass({
6161
};
6262
},
6363

64-
_renderText: function(text) {
64+
_renderText: function(text: string) { // TODO no return type yet
6565
return <Text text={text} />;
6666
},
6767

68-
_renderImageRange: function(text, range) {
68+
_renderImageRange: function(text: string, range) { // TODO no return type yet
6969
var image = range.image;
7070
if (image) {
7171
return (
@@ -79,10 +79,10 @@ var MyComponent3 = React.createClass({
7979
},
8080

8181
autobindMe: function() {},
82-
dontAutobindMe: function() {},
82+
dontAutobindMe: function(): number { return 12; },
8383

8484
// Function comment
85-
_renderRange: function(text, range) {
85+
_renderRange: function(text: string, range, bla: Promise<string>) {
8686
var self = this;
8787

8888
self.dontAutobindMe();

transforms/__testfixtures__/class.output.js

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,61 +18,59 @@ class MyComponent extends React.Component {
1818
};
1919
}
2020

21-
foo() {
21+
foo(): void {
2222
this.setState({heyoo: 24});
2323
}
2424
}
2525

2626
// Class comment
2727
class MyComponent2 extends React.Component {
28-
constructor(props, context) {
29-
super(props, context);
30-
this.foo = this.foo.bind(this);
31-
}
28+
static defaultProps = {a: 1};
3229

33-
foo() {
30+
foo = () => { // flow annotations dont work for now
3431
pass(this.foo);
3532
this.forceUpdate();
36-
}
33+
};
3734
}
3835

39-
MyComponent2.defaultProps = {a: 1};
40-
4136
class MyComponent3 extends React.Component {
37+
static propTypes = {
38+
highlightEntities: React.PropTypes.bool,
39+
linkifyEntities: React.PropTypes.bool,
40+
text: React.PropTypes.shape({
41+
text: React.PropTypes.string,
42+
ranges: React.PropTypes.array,
43+
}).isRequired,
44+
};
45+
46+
static defaultProps = function() {
47+
unboundFunc();
48+
return {
49+
linkifyEntities: true,
50+
highlightEntities: false,
51+
};
52+
}();
53+
54+
static someThing = 10;
55+
static funcThatDoesNothing = function(): void {};
56+
4257
constructor(props, context) {
4358
super(props, context);
44-
this._renderRange = this._renderRange.bind(this);
45-
this._renderText = this._renderText.bind(this);
46-
this.autobindMe = this.autobindMe.bind(this);
4759
props.foo();
4860

4961
this.state = {
5062
heyoo: 23,
5163
};
5264
}
5365

54-
_renderText(text) {
66+
_renderText = (text: string) => { // TODO no return type yet
5567
return <Text text={text} />;
56-
}
57-
58-
_renderImageRange(text, range) {
59-
var image = range.image;
60-
if (image) {
61-
return (
62-
<Image
63-
src={image.uri}
64-
height={image.height / image.scale}
65-
width={image.width / image.scale}
66-
/>
67-
);
68-
}
69-
}
68+
};
7069

71-
autobindMe() {}
72-
dontAutobindMe() {}
70+
autobindMe = () => {};
7371

7472
// Function comment
75-
_renderRange(text, range) {
73+
_renderRange = (text: string, range, bla: Promise<string>) => {
7674
var self = this;
7775

7876
self.dontAutobindMe();
@@ -95,8 +93,23 @@ class MyComponent3 extends React.Component {
9593
}
9694

9795
return text;
96+
};
97+
98+
_renderImageRange(text: string, range) { // TODO no return type yet
99+
var image = range.image;
100+
if (image) {
101+
return (
102+
<Image
103+
src={image.uri}
104+
height={image.height / image.scale}
105+
width={image.width / image.scale}
106+
/>
107+
);
108+
}
98109
}
99110

111+
dontAutobindMe(): number { return 12; }
112+
100113
/* This is a comment */
101114
render() {
102115
var content = this.props.text;
@@ -111,27 +124,6 @@ class MyComponent3 extends React.Component {
111124
}
112125
}
113126

114-
MyComponent3.defaultProps = function() {
115-
foo();
116-
return {
117-
linkifyEntities: true,
118-
highlightEntities: false,
119-
};
120-
}();
121-
122-
MyComponent3.foo = function() {};
123-
124-
MyComponent3.propTypes = {
125-
highlightEntities: React.PropTypes.bool,
126-
linkifyEntities: React.PropTypes.bool,
127-
text: React.PropTypes.shape({
128-
text: React.PropTypes.string,
129-
ranges: React.PropTypes.array,
130-
}).isRequired,
131-
};
132-
133-
MyComponent3.someThing = 10;
134-
135127
var MyComponent4 = React.createClass({
136128
foo: callMeMaybe(),
137129
render: function() {},

transforms/__testfixtures__/export-default-class.output.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,14 @@
55
import React from 'React';
66

77
export default class extends React.Component {
8-
constructor(props, context) {
9-
super(props, context);
10-
11-
this.state = {
12-
foo: 'bar',
13-
};
14-
}
15-
168
static propTypes = {
179
foo: React.PropTypes.string,
1810
};
1911

12+
state = {
13+
foo: 'bar',
14+
};
15+
2016
render() {
2117
return <div />;
2218
}

0 commit comments

Comments
 (0)