Skip to content

Commit a35a238

Browse files
elicwhitefacebook-github-bot
authored andcommitted
RefreshControl ES6 Class
Reviewed By: sahrens Differential Revision: D8219221 fbshipit-source-id: 445243964d64dd5274c1e47bdc137645dc8eecaf
1 parent 2314c83 commit a35a238

File tree

1 file changed

+55
-95
lines changed

1 file changed

+55
-95
lines changed

Libraries/Components/RefreshControl/RefreshControl.js

Lines changed: 55 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,12 @@
1010

1111
'use strict';
1212

13-
const ColorPropType = require('ColorPropType');
14-
const NativeMethodsMixin = require('NativeMethodsMixin');
1513
const Platform = require('Platform');
1614
const React = require('React');
17-
const ReactNative = require('ReactNative');
18-
const PropTypes = require('prop-types');
19-
const ViewPropTypes = require('ViewPropTypes');
15+
const {NativeComponent} = require('ReactNative');
2016

21-
const createReactClass = require('create-react-class');
2217
const requireNativeComponent = require('requireNativeComponent');
18+
const nullthrows = require('fbjs/lib/nullthrows');
2319

2420
import type {ColorValue} from 'StyleSheetTypes';
2521
import type {ViewProps} from 'ViewPropTypes';
@@ -33,29 +29,67 @@ if (Platform.OS === 'android') {
3329
} else {
3430
var RefreshLayoutConsts = {SIZE: {}};
3531
}
32+
type NativeRefreshControlType = Class<NativeComponent<Props>>;
33+
34+
const NativeRefreshControl: NativeRefreshControlType =
35+
Platform.OS === 'ios'
36+
? (requireNativeComponent('RCTRefreshControl'): any)
37+
: (requireNativeComponent('AndroidSwipeRefreshLayout'): any);
3638

3739
type IOSProps = $ReadOnly<{|
40+
/**
41+
* The color of the refresh indicator.
42+
*/
3843
tintColor?: ?ColorValue,
44+
/**
45+
* Title color.
46+
*/
3947
titleColor?: ?ColorValue,
48+
/**
49+
* The title displayed under the refresh indicator.
50+
*/
4051
title?: ?string,
4152
|}>;
4253

4354
type AndroidProps = $ReadOnly<{|
55+
/**
56+
* Whether the pull to refresh functionality is enabled.
57+
*/
4458
enabled?: ?boolean,
59+
/**
60+
* The colors (at least one) that will be used to draw the refresh indicator.
61+
*/
4562
colors?: ?$ReadOnlyArray<ColorValue>,
63+
/**
64+
* The background color of the refresh indicator.
65+
*/
4666
progressBackgroundColor?: ?ColorValue,
67+
/**
68+
* Size of the refresh indicator, see RefreshControl.SIZE.
69+
*/
4770
size?: ?(
4871
| typeof RefreshLayoutConsts.SIZE.DEFAULT
4972
| typeof RefreshLayoutConsts.SIZE.LARGE
5073
),
74+
/**
75+
* Progress view top offset
76+
*/
5177
progressViewOffset?: ?number,
5278
|}>;
5379

5480
type Props = $ReadOnly<{|
5581
...ViewProps,
5682
...IOSProps,
5783
...AndroidProps,
84+
85+
/**
86+
* Called when the view starts refreshing.
87+
*/
5888
onRefresh?: ?Function,
89+
90+
/**
91+
* Whether the view should be indicating an active refresh.
92+
*/
5993
refreshing: boolean,
6094
|}>;
6195

@@ -104,87 +138,29 @@ type Props = $ReadOnly<{|
104138
* __Note:__ `refreshing` is a controlled prop, this is why it needs to be set to true
105139
* in the `onRefresh` function otherwise the refresh indicator will stop immediately.
106140
*/
107-
const RefreshControl = createReactClass({
108-
displayName: 'RefreshControl',
109-
statics: {
110-
SIZE: RefreshLayoutConsts.SIZE,
111-
},
112-
113-
mixins: [NativeMethodsMixin],
114-
115-
propTypes: {
116-
...ViewPropTypes,
117-
/**
118-
* Called when the view starts refreshing.
119-
*/
120-
onRefresh: PropTypes.func,
121-
/**
122-
* Whether the view should be indicating an active refresh.
123-
*/
124-
refreshing: PropTypes.bool.isRequired,
125-
/**
126-
* The color of the refresh indicator.
127-
* @platform ios
128-
*/
129-
tintColor: ColorPropType,
130-
/**
131-
* Title color.
132-
* @platform ios
133-
*/
134-
titleColor: ColorPropType,
135-
/**
136-
* The title displayed under the refresh indicator.
137-
* @platform ios
138-
*/
139-
title: PropTypes.string,
140-
/**
141-
* Whether the pull to refresh functionality is enabled.
142-
* @platform android
143-
*/
144-
enabled: PropTypes.bool,
145-
/**
146-
* The colors (at least one) that will be used to draw the refresh indicator.
147-
* @platform android
148-
*/
149-
colors: PropTypes.arrayOf(ColorPropType),
150-
/**
151-
* The background color of the refresh indicator.
152-
* @platform android
153-
*/
154-
progressBackgroundColor: ColorPropType,
155-
/**
156-
* Size of the refresh indicator, see RefreshControl.SIZE.
157-
* @platform android
158-
*/
159-
size: PropTypes.oneOf([
160-
RefreshLayoutConsts.SIZE.DEFAULT,
161-
RefreshLayoutConsts.SIZE.LARGE,
162-
]),
163-
/**
164-
* Progress view top offset
165-
* @platform android
166-
*/
167-
progressViewOffset: PropTypes.number,
168-
},
169-
170-
_nativeRef: (null: any),
171-
_lastNativeRefreshing: false,
141+
class RefreshControl extends React.Component<Props> {
142+
static SIZE = RefreshLayoutConsts.SIZE;
143+
144+
_nativeRef: ?React.ElementRef<NativeRefreshControlType> = null;
145+
_lastNativeRefreshing = false;
172146

173147
componentDidMount() {
174148
this._lastNativeRefreshing = this.props.refreshing;
175-
},
149+
}
176150

177-
componentDidUpdate(prevProps: {refreshing: boolean}) {
151+
componentDidUpdate(prevProps: Props) {
178152
// RefreshControl is a controlled component so if the native refreshing
179153
// value doesn't match the current js refreshing prop update it to
180154
// the js value.
181155
if (this.props.refreshing !== prevProps.refreshing) {
182156
this._lastNativeRefreshing = this.props.refreshing;
183157
} else if (this.props.refreshing !== this._lastNativeRefreshing) {
184-
this._nativeRef.setNativeProps({refreshing: this.props.refreshing});
158+
nullthrows(this._nativeRef).setNativeProps({
159+
refreshing: this.props.refreshing,
160+
});
185161
this._lastNativeRefreshing = this.props.refreshing;
186162
}
187-
},
163+
}
188164

189165
render() {
190166
return (
@@ -196,33 +172,17 @@ const RefreshControl = createReactClass({
196172
onRefresh={this._onRefresh}
197173
/>
198174
);
199-
},
175+
}
200176

201-
_onRefresh() {
177+
_onRefresh = () => {
202178
this._lastNativeRefreshing = true;
203179

204180
this.props.onRefresh && this.props.onRefresh();
205181

206182
// The native component will start refreshing so force an update to
207183
// make sure it stays in sync with the js component.
208184
this.forceUpdate();
209-
},
210-
});
211-
212-
class TypedRefreshControl extends ReactNative.NativeComponent<Props> {
213-
static SIZE = RefreshLayoutConsts.SIZE;
214-
}
215-
216-
if (Platform.OS === 'ios') {
217-
var NativeRefreshControl = requireNativeComponent(
218-
'RCTRefreshControl',
219-
RefreshControl,
220-
);
221-
} else if (Platform.OS === 'android') {
222-
var NativeRefreshControl = requireNativeComponent(
223-
'AndroidSwipeRefreshLayout',
224-
RefreshControl,
225-
);
185+
};
226186
}
227187

228-
module.exports = ((RefreshControl: any): Class<TypedRefreshControl>);
188+
module.exports = RefreshControl;

0 commit comments

Comments
 (0)