Skip to content

Commit 3bf8f38

Browse files
committed
chore: optimize code.
1 parent 4be6484 commit 3bf8f38

File tree

5 files changed

+230
-179
lines changed

5 files changed

+230
-179
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@
55
# IDE
66
.idea
77

8+
node_modules
89
npm-debug.log
10+
package-lock.json
911
example/package-lock.json

components/ModalDropdown.js

Lines changed: 103 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@ import {
2222
ActivityIndicator,
2323
} from 'react-native';
2424

25-
const PropTypes = require('prop-types');
25+
import PropTypes from 'prop-types';
2626

27-
const TOUCHABLE_ELEMENTS = ['TouchableHighlight', 'TouchableOpacity', 'TouchableWithoutFeedback', 'TouchableNativeFeedback'];
27+
const TOUCHABLE_ELEMENTS = [
28+
'TouchableHighlight',
29+
'TouchableOpacity',
30+
'TouchableWithoutFeedback',
31+
'TouchableNativeFeedback'
32+
];
2833

2934
export default class ModalDropdown extends Component {
3035
static propTypes = {
@@ -75,32 +80,32 @@ export default class ModalDropdown extends Component {
7580
this._nextIndex = null;
7681

7782
this.state = {
78-
disabled: props.disabled,
7983
accessible: !!props.accessible,
80-
loading: props.options === null || props.options === undefined,
84+
loading: !props.options,
8185
showDropdown: false,
8286
buttonText: props.defaultValue,
8387
selectedIndex: props.defaultIndex
8488
};
8589
}
8690

8791
componentWillReceiveProps(nextProps) {
88-
let buttonText = this._nextValue == null ? this.state.buttonText : this._nextValue.toString();
89-
let selectedIndex = this._nextIndex == null ? this.state.selectedIndex : this._nextIndex;
92+
let {buttonText, selectedIndex} = this.state;
93+
const {defaultIndex, defaultValue, options} = nextProps;
94+
buttonText = this._nextValue == null ? buttonText : this._nextValue.toString();
95+
selectedIndex = this._nextIndex == null ? selectedIndex : this._nextIndex;
9096
if (selectedIndex < 0) {
91-
selectedIndex = nextProps.defaultIndex;
97+
selectedIndex = defaultIndex;
9298
if (selectedIndex < 0) {
93-
buttonText = nextProps.defaultValue;
99+
buttonText = defaultValue;
94100
}
95101
}
96102
this._nextValue = null;
97103
this._nextIndex = null;
98104

99105
this.setState({
100-
disabled: nextProps.disabled,
101-
loading: nextProps.options == null,
102-
buttonText: buttonText,
103-
selectedIndex: selectedIndex
106+
loading: !options,
107+
buttonText,
108+
selectedIndex
104109
});
105110
}
106111

@@ -158,18 +163,23 @@ export default class ModalDropdown extends Component {
158163
}
159164

160165
_renderButton() {
166+
const {disabled, accessible, children, textStyle} = this.props;
167+
const {buttonText} = this.state;
168+
161169
return (
162170
<TouchableOpacity ref={button => this._button = button}
163-
disabled={this.props.disabled}
164-
accessible={this.props.accessible}
165-
onPress={this._onButtonPress.bind(this)}>
171+
disabled={disabled}
172+
accessible={accessible}
173+
onPress={this._onButtonPress}
174+
>
166175
{
167-
this.props.children ||
176+
children ||
168177
(
169178
<View style={styles.button}>
170-
<Text style={[styles.buttonText, this.props.textStyle]}
171-
numberOfLines={1}>
172-
{this.state.buttonText}
179+
<Text style={[styles.buttonText, textStyle]}
180+
numberOfLines={1}
181+
>
182+
{buttonText}
173183
</Text>
174184
</View>
175185
)
@@ -178,29 +188,34 @@ export default class ModalDropdown extends Component {
178188
);
179189
}
180190

181-
_onButtonPress() {
182-
if (!this.props.onDropdownWillShow ||
183-
this.props.onDropdownWillShow() !== false) {
191+
_onButtonPress = () => {
192+
const {onDropdownWillShow} = this.props;
193+
if (!onDropdownWillShow ||
194+
onDropdownWillShow() !== false) {
184195
this.show();
185196
}
186-
}
197+
};
187198

188199
_renderModal() {
189-
if (this.state.showDropdown && this._buttonFrame) {
200+
const {animated, accessible, dropdownStyle} = this.props;
201+
const {showDropdown, loading} = this.state;
202+
if (showDropdown && this._buttonFrame) {
190203
const frameStyle = this._calcPosition();
191-
const animationType = this.props.animated ? 'fade' : 'none';
204+
const animationType = animated ? 'fade' : 'none';
192205
return (
193206
<Modal animationType={animationType}
194207
visible={true}
195208
transparent={true}
196-
onRequestClose={this._onRequestClose.bind(this)}
197-
supportedOrientations={['portrait', 'portrait-upside-down', 'landscape', 'landscape-left', 'landscape-right']}>
198-
<TouchableWithoutFeedback accessible={this.props.accessible}
199-
disabled={!this.state.showDropdown}
200-
onPress={this._onModalPress.bind(this)}>
209+
onRequestClose={this._onRequestClose}
210+
supportedOrientations={['portrait', 'portrait-upside-down', 'landscape', 'landscape-left', 'landscape-right']}
211+
>
212+
<TouchableWithoutFeedback accessible={accessible}
213+
disabled={!showDropdown}
214+
onPress={this._onModalPress}
215+
>
201216
<View style={styles.modal}>
202-
<View style={[styles.dropdown, this.props.dropdownStyle, frameStyle]}>
203-
{this.state.loading ? this._renderLoading() : this._renderDropdown()}
217+
<View style={[styles.dropdown, dropdownStyle, frameStyle]}>
218+
{loading ? this._renderLoading() : this._renderDropdown()}
204219
</View>
205220
</View>
206221
</TouchableWithoutFeedback>
@@ -210,54 +225,54 @@ export default class ModalDropdown extends Component {
210225
}
211226

212227
_calcPosition() {
228+
const {dropdownStyle, style, adjustFrame} = this.props;
229+
213230
const dimensions = Dimensions.get('window');
214231
const windowWidth = dimensions.width;
215232
const windowHeight = dimensions.height;
216233

217-
const dropdownHeight = (this.props.dropdownStyle && StyleSheet.flatten(this.props.dropdownStyle).height) ||
234+
const dropdownHeight = (dropdownStyle && StyleSheet.flatten(dropdownStyle).height) ||
218235
StyleSheet.flatten(styles.dropdown).height;
219236

220237
const bottomSpace = windowHeight - this._buttonFrame.y - this._buttonFrame.h;
221238
const rightSpace = windowWidth - this._buttonFrame.x;
222239
const showInBottom = bottomSpace >= dropdownHeight || bottomSpace >= this._buttonFrame.y;
223240
const showInLeft = rightSpace >= this._buttonFrame.x;
224241

225-
let style = {
242+
const positionStyle = {
226243
height: dropdownHeight,
227244
top: showInBottom ? this._buttonFrame.y + this._buttonFrame.h : Math.max(0, this._buttonFrame.y - dropdownHeight),
228245
};
229246

230247
if (showInLeft) {
231-
style.left = this._buttonFrame.x;
248+
positionStyle.left = this._buttonFrame.x;
232249
} else {
233-
const dropdownWidth = (this.props.dropdownStyle && StyleSheet.flatten(this.props.dropdownStyle).width) ||
234-
(this.props.style && StyleSheet.flatten(this.props.style).width) || -1;
250+
const dropdownWidth = (dropdownStyle && StyleSheet.flatten(dropdownStyle).width) ||
251+
(style && StyleSheet.flatten(style).width) || -1;
235252
if (dropdownWidth !== -1) {
236-
style.width = dropdownWidth;
253+
positionStyle.width = dropdownWidth;
237254
}
238-
style.right = rightSpace - this._buttonFrame.w;
255+
positionStyle.right = rightSpace - this._buttonFrame.w;
239256
}
240257

241-
if (this.props.adjustFrame) {
242-
style = this.props.adjustFrame(style) || style;
243-
}
244-
245-
return style;
258+
return adjustFrame ? adjustFrame(positionStyle) : positionStyle;
246259
}
247260

248-
_onRequestClose() {
249-
if (!this.props.onDropdownWillHide ||
250-
this.props.onDropdownWillHide() !== false) {
261+
_onRequestClose = () => {
262+
const {onDropdownWillHide} = this.props;
263+
if (!onDropdownWillHide ||
264+
onDropdownWillHide() !== false) {
251265
this.hide();
252266
}
253-
}
267+
};
254268

255-
_onModalPress() {
256-
if (!this.props.onDropdownWillHide ||
257-
this.props.onDropdownWillHide() !== false) {
269+
_onModalPress = () => {
270+
const {onDropdownWillHide} = this.props;
271+
if (!onDropdownWillHide ||
272+
onDropdownWillHide() !== false) {
258273
this.hide();
259274
}
260-
}
275+
};
261276

262277
_renderLoading() {
263278
return (
@@ -266,79 +281,80 @@ export default class ModalDropdown extends Component {
266281
}
267282

268283
_renderDropdown() {
284+
const {scrollEnabled, renderSeparator, showsVerticalScrollIndicator, keyboardShouldPersistTaps} = this.props;
269285
return (
270-
<ListView scrollEnabled={this.props.scrollEnabled}
286+
<ListView scrollEnabled={scrollEnabled}
271287
style={styles.list}
272288
dataSource={this._dataSource}
273-
renderRow={this._renderRow.bind(this)}
274-
renderSeparator={this.props.renderSeparator || this._renderSeparator.bind(this)}
289+
renderRow={this._renderRow}
290+
renderSeparator={renderSeparator || this._renderSeparator}
275291
automaticallyAdjustContentInsets={false}
276-
showsVerticalScrollIndicator={this.props.showsVerticalScrollIndicator}
277-
keyboardShouldPersistTaps={this.props.keyboardShouldPersistTaps}
292+
showsVerticalScrollIndicator={showsVerticalScrollIndicator}
293+
keyboardShouldPersistTaps={keyboardShouldPersistTaps}
278294
/>
279295
);
280296
}
281297

282298
get _dataSource() {
299+
const {options} = this.props;
283300
const ds = new ListView.DataSource({
284301
rowHasChanged: (r1, r2) => r1 !== r2
285302
});
286-
return ds.cloneWithRows(this.props.options);
303+
return ds.cloneWithRows(options);
287304
}
288305

289-
_renderRow(rowData, sectionID, rowID, highlightRow) {
306+
_renderRow = (rowData, sectionID, rowID, highlightRow) => {
307+
const {renderRow, dropdownTextStyle, dropdownTextHighlightStyle, accessible} = this.props;
308+
const {selectedIndex} = this.state;
290309
const key = `row_${rowID}`;
291-
const highlighted = rowID == this.state.selectedIndex;
292-
const row = !this.props.renderRow ?
310+
const highlighted = rowID == selectedIndex;
311+
const row = !renderRow ?
293312
(<Text style={[
294313
styles.rowText,
295-
this.props.dropdownTextStyle,
314+
dropdownTextStyle,
296315
highlighted && styles.highlightedRowText,
297-
highlighted && this.props.dropdownTextHighlightStyle
316+
highlighted && dropdownTextHighlightStyle
298317
]}
299318
>
300319
{rowData}
301320
</Text>) :
302-
this.props.renderRow(rowData, rowID, highlighted);
321+
renderRow(rowData, rowID, highlighted);
303322
const preservedProps = {
304-
key: key,
305-
accessible: this.props.accessible,
323+
key,
324+
accessible,
306325
onPress: () => this._onRowPress(rowData, sectionID, rowID, highlightRow),
307326
};
308327
if (TOUCHABLE_ELEMENTS.find(name => name == row.type.displayName)) {
309328
const props = {...row.props};
310329
props.key = preservedProps.key;
311330
props.onPress = preservedProps.onPress;
331+
const {children} = row.props;
312332
switch (row.type.displayName) {
313-
case 'TouchableHighlight':
314-
{
333+
case 'TouchableHighlight': {
315334
return (
316335
<TouchableHighlight {...props}>
317-
{row.props.children}
336+
{children}
318337
</TouchableHighlight>
319338
);
320339
}
321-
case 'TouchableOpacity':
322-
{
340+
case 'TouchableOpacity': {
323341
return (
324342
<TouchableOpacity {...props}>
325-
{row.props.children}
343+
{children}
326344
</TouchableOpacity>
327345
);
328346
}
329-
case 'TouchableWithoutFeedback':
330-
{
347+
case 'TouchableWithoutFeedback': {
331348
return (
332349
<TouchableWithoutFeedback {...props}>
333-
{row.props.children}
350+
{children}
334351
</TouchableWithoutFeedback>
335352
);
336353
}
337-
case 'TouchableNativeFeedback':
338-
{
354+
case 'TouchableNativeFeedback': {
339355
return (
340356
<TouchableNativeFeedback {...props}>
341-
{row.props.children}
357+
{children}
342358
</TouchableNativeFeedback>
343359
);
344360
}
@@ -351,10 +367,10 @@ export default class ModalDropdown extends Component {
351367
{row}
352368
</TouchableHighlight>
353369
);
354-
}
370+
};
355371

356372
_onRowPress(rowData, sectionID, rowID, highlightRow) {
357-
const { onSelect, renderButtonText, onDropdownWillHide } = this.props;
373+
const {onSelect, renderButtonText, onDropdownWillHide} = this.props;
358374
if (!onSelect || onSelect(rowID, rowData) !== false) {
359375
highlightRow(sectionID, rowID);
360376
this._nextValue = rowData;
@@ -371,12 +387,14 @@ export default class ModalDropdown extends Component {
371387
}
372388
}
373389

374-
_renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
390+
_renderSeparator = (sectionID, rowID, adjacentRowHighlighted) => {
375391
const key = `spr_${rowID}`;
376-
return (<View style={styles.separator}
377-
key={key}
378-
/>);
379-
}
392+
return (
393+
<View style={styles.separator}
394+
key={key}
395+
/>
396+
);
397+
};
380398
}
381399

382400
const styles = StyleSheet.create({

0 commit comments

Comments
 (0)