1
+ import Immutable from 'immutable' ;
1
2
import PropTypes from 'prop-types' ;
2
3
import React , { Component } from 'react' ;
3
- import { Text , View , Button } from 'react-native' ;
4
+ import { Text , View , Button , RefreshControl } from 'react-native' ;
4
5
5
6
import style from './styles' ;
6
7
8
+ const EMPTY_LIST = Immutable . List ( ) ;
9
+ const MOCK_DELAY = 800 ;
10
+
7
11
class GenericListExample extends Component {
8
12
9
13
static propTypes = {
@@ -20,58 +24,190 @@ class GenericListExample extends Component {
20
24
componentWillMount ( ) {
21
25
const { initialDataA, initialDataB } = this . props ;
22
26
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 ( ) {
23
103
this . setState ( {
24
- listDataA : initialDataA ,
25
- listDataB : initialDataB ,
104
+ listA : {
105
+ ...this . defaultStateA ,
106
+ } ,
107
+ listB : {
108
+ ...this . defaultStateB ,
109
+ } ,
26
110
} ) ;
27
111
}
28
112
29
- changeDataA ( ) {
113
+ toggleLoadingState ( ) {
30
114
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
+ } ,
32
125
} ) ;
33
126
}
34
127
35
- changeDataB ( ) {
128
+ toggleErrorState ( ) {
36
129
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
+ } ,
38
140
} ) ;
39
141
}
40
142
41
143
render ( ) {
42
- const { listDataA , listDataB } = this . state ;
144
+ const { listA , listB } = this . state ;
43
145
const { ListComponent, extraPropsA, extraPropsB, listComponentProps } = this . props ;
44
146
147
+ const emptyTextA = listA . isLoading ? 'Loading...' : listA . errorMsg ;
148
+ const emptyTextB = listB . isLoading ? 'Loading...' : listB . errorMsg ;
149
+
45
150
return (
46
151
< View style = { style . container } >
47
152
< Text style = { style . title } >
48
153
{ ListComponent . displayName || ListComponent . name }
49
154
</ 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 } >
51
173
< View style = { style . list } >
52
- < View style = { style . button } >
174
+ < View style = { style . listButton } >
53
175
< Button
54
176
onPress = { ( ) => this . changeDataA ( ) }
55
- title = "Update Data"
177
+ title = "Update Data (or pull-refresh) "
56
178
/>
57
179
</ View >
58
180
< ListComponent
59
- immutableData = { listDataA }
181
+ refreshControl = {
182
+ < RefreshControl
183
+ refreshing = { listA . isLoading }
184
+ onRefresh = { ( ) => this . changeDataA ( MOCK_DELAY ) }
185
+ />
186
+ }
60
187
{ ...listComponentProps }
61
188
{ ...extraPropsA }
189
+ immutableData = { listA . data }
190
+ renderEmptyInList = { emptyTextA }
62
191
/>
63
192
</ View >
64
193
< View style = { style . list } >
65
- < View style = { style . button } >
194
+ < View style = { style . listButton } >
66
195
< Button
67
196
onPress = { ( ) => this . changeDataB ( ) }
68
- title = "Update Data"
197
+ title = "Update Data (or pull-refresh) "
69
198
/>
70
199
</ View >
71
200
< ListComponent
72
- immutableData = { listDataB }
201
+ refreshControl = {
202
+ < RefreshControl
203
+ refreshing = { listB . isLoading }
204
+ onRefresh = { ( ) => this . changeDataB ( MOCK_DELAY ) }
205
+ />
206
+ }
73
207
{ ...listComponentProps }
74
208
{ ...extraPropsB }
209
+ immutableData = { listB . data }
210
+ renderEmptyInList = { emptyTextB }
75
211
/>
76
212
</ View >
77
213
</ View >
0 commit comments