Skip to content

Commit 3172949

Browse files
committed
✨ [Example] Significantly improve the example app (add states)
1 parent b2dc557 commit 3172949

File tree

3 files changed

+181
-32
lines changed

3 files changed

+181
-32
lines changed

example/src/GenericListExample.js

Lines changed: 151 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
import Immutable from 'immutable';
12
import PropTypes from 'prop-types';
23
import React, { Component } from 'react';
3-
import { Text, View, Button } from 'react-native';
4+
import { Text, View, Button, RefreshControl } from 'react-native';
45

56
import style from './styles';
67

8+
const EMPTY_LIST = Immutable.List();
9+
const MOCK_DELAY = 800;
10+
711
class GenericListExample extends Component {
812

913
static propTypes = {
@@ -20,58 +24,190 @@ class GenericListExample extends Component {
2024
componentWillMount() {
2125
const { initialDataA, initialDataB } = this.props;
2226

27+
this.defaultStateA.data = initialDataA;
28+
this.defaultStateB.data = initialDataB;
29+
30+
this.setState({
31+
listA: {
32+
...this.defaultStateA,
33+
},
34+
listB: {
35+
...this.defaultStateB,
36+
},
37+
});
38+
}
39+
40+
defaultStateA = {
41+
data: undefined, // Will be manually set on mount.
42+
isLoading: false,
43+
errorMsg: undefined,
44+
};
45+
46+
defaultStateB = {
47+
data: undefined, // Will be manually set on mount.
48+
isLoading: false,
49+
errorMsg: undefined,
50+
};
51+
52+
changeDataA(delay = 0) {
53+
const { listA } = this.state;
54+
const { dataMutatorA } = this.props;
55+
56+
if (delay) {
57+
this.setState({
58+
listA: {
59+
...listA,
60+
isLoading: true,
61+
},
62+
});
63+
}
64+
65+
setTimeout(() => {
66+
this.setState({
67+
listA: {
68+
...listA,
69+
data: dataMutatorA(listA.data),
70+
isLoading: false,
71+
errorMsg: undefined,
72+
},
73+
});
74+
}, delay);
75+
}
76+
77+
changeDataB(delay = 0) {
78+
const { listB } = this.state;
79+
const { dataMutatorB } = this.props;
80+
81+
if (delay) {
82+
this.setState({
83+
listB: {
84+
...listB,
85+
isLoading: true,
86+
},
87+
});
88+
}
89+
90+
setTimeout(() => {
91+
this.setState({
92+
listB: {
93+
...listB,
94+
data: dataMutatorB(listB.data),
95+
isLoading: false,
96+
errorMsg: undefined,
97+
},
98+
});
99+
}, delay);
100+
}
101+
102+
toggleDefaultState() {
23103
this.setState({
24-
listDataA: initialDataA,
25-
listDataB: initialDataB,
104+
listA: {
105+
...this.defaultStateA,
106+
},
107+
listB: {
108+
...this.defaultStateB,
109+
},
26110
});
27111
}
28112

29-
changeDataA() {
113+
toggleLoadingState() {
30114
this.setState({
31-
listDataA: this.props.dataMutatorA(this.state.listDataA),
115+
listA: {
116+
...this.defaultStateA,
117+
data: EMPTY_LIST,
118+
isLoading: true,
119+
},
120+
listB: {
121+
...this.defaultStateB,
122+
data: EMPTY_LIST,
123+
isLoading: true,
124+
},
32125
});
33126
}
34127

35-
changeDataB() {
128+
toggleErrorState() {
36129
this.setState({
37-
listDataB: this.props.dataMutatorB(this.state.listDataB),
130+
listA: {
131+
...this.defaultStateA,
132+
data: EMPTY_LIST,
133+
errorMsg: 'Error! Fake data A has gone rogue!',
134+
},
135+
listB: {
136+
...this.defaultStateB,
137+
data: EMPTY_LIST,
138+
errorMsg: 'Error! Fake data B has gone rogue!',
139+
},
38140
});
39141
}
40142

41143
render() {
42-
const { listDataA, listDataB } = this.state;
144+
const { listA, listB } = this.state;
43145
const { ListComponent, extraPropsA, extraPropsB, listComponentProps } = this.props;
44146

147+
const emptyTextA = listA.isLoading ? 'Loading...' : listA.errorMsg;
148+
const emptyTextB = listB.isLoading ? 'Loading...' : listB.errorMsg;
149+
45150
return (
46151
<View style={style.container}>
47152
<Text style={style.title}>
48153
{ListComponent.displayName || ListComponent.name}
49154
</Text>
50-
<View style={style.sideBySideLists}>
155+
<View style={style.controlPanelContainer}>
156+
<Text style={style.controlPanelLabel}>
157+
State:
158+
</Text>
159+
<Button
160+
onPress={() => this.toggleDefaultState()}
161+
title="'Default'"
162+
/>
163+
<Button
164+
onPress={() => this.toggleLoadingState()}
165+
title="'Loading'"
166+
/>
167+
<Button
168+
onPress={() => this.toggleErrorState()}
169+
title="'Error'"
170+
/>
171+
</View>
172+
<View style={style.listContainer}>
51173
<View style={style.list}>
52-
<View style={style.button}>
174+
<View style={style.listButton}>
53175
<Button
54176
onPress={() => this.changeDataA()}
55-
title="Update Data"
177+
title="Update Data (or pull-refresh)"
56178
/>
57179
</View>
58180
<ListComponent
59-
immutableData={listDataA}
181+
refreshControl={
182+
<RefreshControl
183+
refreshing={listA.isLoading}
184+
onRefresh={() => this.changeDataA(MOCK_DELAY)}
185+
/>
186+
}
60187
{...listComponentProps}
61188
{...extraPropsA}
189+
immutableData={listA.data}
190+
renderEmptyInList={emptyTextA}
62191
/>
63192
</View>
64193
<View style={style.list}>
65-
<View style={style.button}>
194+
<View style={style.listButton}>
66195
<Button
67196
onPress={() => this.changeDataB()}
68-
title="Update Data"
197+
title="Update Data (or pull-refresh)"
69198
/>
70199
</View>
71200
<ListComponent
72-
immutableData={listDataB}
201+
refreshControl={
202+
<RefreshControl
203+
refreshing={listB.isLoading}
204+
onRefresh={() => this.changeDataB(MOCK_DELAY)}
205+
/>
206+
}
73207
{...listComponentProps}
74208
{...extraPropsB}
209+
immutableData={listB.data}
210+
renderEmptyInList={emptyTextB}
75211
/>
76212
</View>
77213
</View>

example/src/styles.js

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,44 @@ const style = StyleSheet.create({
1010
title: {
1111
fontSize: 20,
1212
textAlign: 'center',
13-
margin: 20,
13+
padding: 24,
1414
},
15-
button: {
16-
padding: 20,
17-
paddingTop: 0,
15+
controlPanelContainer: {
16+
flexDirection: 'row',
17+
justifyContent: 'center',
18+
alignItems: 'center',
19+
marginBottom: 12,
20+
borderWidth: 2,
21+
borderRadius: 8,
22+
borderColor: 'black',
23+
backgroundColor: 'transparent',
1824
},
19-
listRow: {
20-
fontSize: 13,
25+
controlPanelLabel: {
26+
fontSize: 18,
27+
padding: 8,
28+
},
29+
listContainer: {
30+
flex: 1,
31+
flexDirection: 'row',
32+
},
33+
list: {
34+
flex: 1,
35+
},
36+
listButton: {
37+
margin: 4,
38+
},
39+
listRowItem: {
40+
fontSize: 14,
2141
textAlign: 'center',
2242
color: '#333333',
2343
marginBottom: 5,
2444
},
25-
listHeader: {
45+
listHeaderItem: {
2646
fontSize: 16,
2747
textAlign: 'center',
2848
color: '#333333',
2949
marginBottom: 5,
3050
},
31-
sideBySideLists: {
32-
flex: 1,
33-
flexDirection: 'row',
34-
},
35-
list: {
36-
flex: 1,
37-
},
3851
});
3952

4053
export default style;

example/src/utils.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ import style from './styles';
66
const utils = {
77

88
renderRow(rowData) {
9-
return <Text style={style.listRow}>{rowData}</Text>;
9+
return <Text style={style.listRowItem}>{rowData}</Text>;
1010
},
1111

1212
// eslint-disable-next-line react/prop-types
1313
renderItem({ item }) {
14-
return <Text style={style.listRow}>{item}</Text>;
14+
return <Text style={style.listRowItem}>{item}</Text>;
1515
},
1616

1717
renderSectionHeader(sectionData, category) {
1818
return (
1919
<View>
20-
<Text style={style.listHeader}>{category}</Text>
20+
<Text style={style.listHeaderItem}>{category}</Text>
2121
</View>
2222
);
2323
},

0 commit comments

Comments
 (0)