1+ import Immutable from 'immutable' ;
12import PropTypes from 'prop-types' ;
23import React , { Component } from 'react' ;
3- import { Text , View , Button } from 'react-native' ;
4+ import { Text , View , Button , RefreshControl } from 'react-native' ;
45
56import style from './styles' ;
67
8+ const EMPTY_LIST = Immutable . List ( ) ;
9+ const MOCK_DELAY = 800 ;
10+
711class 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 >
0 commit comments