@@ -16,7 +16,7 @@ const { array, func, object, any } = React.PropTypes;
16
16
function eachComponents ( components , iterator ) {
17
17
for ( let i = 0 , l = components . length ; i < l ; i ++ ) { // eslint-disable-line id-length
18
18
if ( typeof components [ i ] === 'object' ) {
19
- for ( let [ key , value ] of Object . entries ( components [ i ] ) ) {
19
+ for ( const [ key , value ] of Object . entries ( components [ i ] ) ) {
20
20
iterator ( value , i , key ) ;
21
21
}
22
22
} else {
@@ -35,36 +35,48 @@ function filterAndFlattenComponents(components) {
35
35
return flattened ;
36
36
}
37
37
38
- function loadAsyncConnect ( { components, filter = ( ) => true , ...rest } ) {
39
- let async = false ;
38
+ function loadAsyncConnect ( { components, fetchDeferred, ...rest } ) {
39
+ let hasAsync = false ;
40
+ let loadDeferred = false ;
40
41
const promise = Promise . all ( filterAndFlattenComponents ( components ) . map ( Component => {
41
42
const asyncItems = Component . reduxAsyncConnect ;
42
43
43
44
return Promise . all ( asyncItems . reduce ( ( itemsResults , item ) => {
44
45
let promiseOrResult = item . promise ( rest ) ;
45
46
46
- if ( filter ( item , Component ) ) {
47
+ if ( ! loadDeferred && ! fetchDeferred ) {
48
+ loadDeferred = item . deferred ;
49
+ }
50
+
51
+ const loadItem = fetchDeferred ? item . deferred : item ;
52
+
53
+ if ( loadItem ) {
47
54
if ( promiseOrResult && promiseOrResult . then instanceof Function ) {
48
- async = true ;
55
+ hasAsync = true ;
49
56
promiseOrResult = promiseOrResult . catch ( error => ( { error} ) ) ;
50
57
}
51
58
return [ ...itemsResults , promiseOrResult ] ;
52
- } else {
53
- return itemsResults ;
54
59
}
60
+
61
+ return itemsResults ;
55
62
} , [ ] ) ) . then ( results => {
56
- return asyncItems . reduce ( ( result , item , i ) => ( { ...result , [ item . key ] : results [ i ] } ) , { } ) ;
63
+ return asyncItems . reduce ( ( result , item , index ) =>
64
+ ( { ...result , [ item . key ] : results [ index ] } ) , { } ) ;
57
65
} ) ;
58
66
} ) ) ;
59
67
60
- return { promise, async} ;
68
+ return {
69
+ promise,
70
+ hasAsync,
71
+ loadDeferred,
72
+ } ;
61
73
}
62
74
63
75
export function loadOnServer ( args ) {
64
76
const result = loadAsyncConnect ( args ) ;
65
- if ( result . async ) {
77
+ if ( result . hasAsync ) {
66
78
result . promise . then ( ( ) => {
67
- args . store . dispatch ( endGlobalLoad ( ) ) ;
79
+ args . store . dispatch ( endGlobalLoad ( result . loadDeferred ) ) ;
68
80
} ) ;
69
81
}
70
82
return result . promise ;
@@ -92,10 +104,6 @@ class ReduxAsyncConnect extends React.Component {
92
104
}
93
105
} ;
94
106
95
- isLoaded ( ) {
96
- return this . context . store . getState ( ) . reduxAsyncConnect . loaded ;
97
- }
98
-
99
107
constructor ( props , context ) {
100
108
super ( props , context ) ;
101
109
@@ -106,29 +114,42 @@ class ReduxAsyncConnect extends React.Component {
106
114
107
115
componentDidMount ( ) {
108
116
const dataLoaded = this . isLoaded ( ) ;
117
+ const fetchDeferred = ! this . isDeferredLoaded ( ) ;
109
118
110
- if ( ! dataLoaded ) { // we dont need it if we already made it on server-side
111
- this . loadAsyncData ( this . props ) ;
119
+ if ( ! dataLoaded || fetchDeferred ) { // we dont need it if we already made it on server-side
120
+ this . loadAsyncData ( this . props , fetchDeferred ) ;
112
121
}
113
122
}
114
123
115
124
componentWillReceiveProps ( nextProps ) {
116
- this . loadAsyncData ( nextProps ) ;
125
+ const deferredLoaded = this . isDeferredLoaded ( ) ;
126
+
127
+ if ( deferredLoaded ) {
128
+ this . loadAsyncData ( nextProps ) ;
129
+ }
117
130
}
118
131
119
132
shouldComponentUpdate ( nextProps , nextState ) {
120
133
return this . state . propsToShow !== nextState . propsToShow ;
121
134
}
122
135
123
- loadAsyncData ( props ) {
136
+ isLoaded ( ) {
137
+ return this . context . store . getState ( ) . reduxAsyncConnect . loaded ;
138
+ }
139
+
140
+ isDeferredLoaded ( ) {
141
+ return this . context . store . getState ( ) . reduxAsyncConnect . deferredLoaded ;
142
+ }
143
+
144
+ loadAsyncData ( props , fetchDeferred ) {
124
145
const store = this . context . store ;
125
- const loadResult = loadAsyncConnect ( { ...props , store} ) ;
146
+ const loadResult = loadAsyncConnect ( { ...props , store, fetchDeferred } ) ;
126
147
127
148
loadDataCounter ++ ;
128
149
129
- if ( loadResult . async ) {
150
+ if ( loadResult . hasAsync ) {
130
151
this . props . beginGlobalLoad ( ) ;
131
- ( loadDataCounterOriginal => {
152
+ ( ( loadDataCounterOriginal ) => {
132
153
loadResult . promise . then ( ( ) => {
133
154
// We need to change propsToShow only if loadAsyncData that called this promise
134
155
// is the last invocation of loadAsyncData method. Otherwise we can face situation
@@ -146,7 +167,7 @@ class ReduxAsyncConnect extends React.Component {
146
167
}
147
168
148
169
render ( ) {
149
- const { propsToShow} = this . state ;
170
+ const { propsToShow } = this . state ;
150
171
return propsToShow && this . props . render ( propsToShow ) ;
151
172
}
152
173
}
0 commit comments