@@ -16,7 +16,7 @@ const { array, func, object, any } = React.PropTypes;
1616function eachComponents ( components , iterator ) {
1717 for ( let i = 0 , l = components . length ; i < l ; i ++ ) { // eslint-disable-line id-length
1818 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 ] ) ) {
2020 iterator ( value , i , key ) ;
2121 }
2222 } else {
@@ -35,36 +35,48 @@ function filterAndFlattenComponents(components) {
3535 return flattened ;
3636}
3737
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 ;
4041 const promise = Promise . all ( filterAndFlattenComponents ( components ) . map ( Component => {
4142 const asyncItems = Component . reduxAsyncConnect ;
4243
4344 return Promise . all ( asyncItems . reduce ( ( itemsResults , item ) => {
4445 let promiseOrResult = item . promise ( rest ) ;
4546
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 ) {
4754 if ( promiseOrResult && promiseOrResult . then instanceof Function ) {
48- async = true ;
55+ hasAsync = true ;
4956 promiseOrResult = promiseOrResult . catch ( error => ( { error} ) ) ;
5057 }
5158 return [ ...itemsResults , promiseOrResult ] ;
52- } else {
53- return itemsResults ;
5459 }
60+
61+ return itemsResults ;
5562 } , [ ] ) ) . 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 ] } ) , { } ) ;
5765 } ) ;
5866 } ) ) ;
5967
60- return { promise, async} ;
68+ return {
69+ promise,
70+ hasAsync,
71+ loadDeferred,
72+ } ;
6173}
6274
6375export function loadOnServer ( args ) {
6476 const result = loadAsyncConnect ( args ) ;
65- if ( result . async ) {
77+ if ( result . hasAsync ) {
6678 result . promise . then ( ( ) => {
67- args . store . dispatch ( endGlobalLoad ( ) ) ;
79+ args . store . dispatch ( endGlobalLoad ( result . loadDeferred ) ) ;
6880 } ) ;
6981 }
7082 return result . promise ;
@@ -92,10 +104,6 @@ class ReduxAsyncConnect extends React.Component {
92104 }
93105 } ;
94106
95- isLoaded ( ) {
96- return this . context . store . getState ( ) . reduxAsyncConnect . loaded ;
97- }
98-
99107 constructor ( props , context ) {
100108 super ( props , context ) ;
101109
@@ -106,29 +114,42 @@ class ReduxAsyncConnect extends React.Component {
106114
107115 componentDidMount ( ) {
108116 const dataLoaded = this . isLoaded ( ) ;
117+ const fetchDeferred = ! this . isDeferredLoaded ( ) ;
109118
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 ) ;
112121 }
113122 }
114123
115124 componentWillReceiveProps ( nextProps ) {
116- this . loadAsyncData ( nextProps ) ;
125+ const deferredLoaded = this . isDeferredLoaded ( ) ;
126+
127+ if ( deferredLoaded ) {
128+ this . loadAsyncData ( nextProps ) ;
129+ }
117130 }
118131
119132 shouldComponentUpdate ( nextProps , nextState ) {
120133 return this . state . propsToShow !== nextState . propsToShow ;
121134 }
122135
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 ) {
124145 const store = this . context . store ;
125- const loadResult = loadAsyncConnect ( { ...props , store} ) ;
146+ const loadResult = loadAsyncConnect ( { ...props , store, fetchDeferred } ) ;
126147
127148 loadDataCounter ++ ;
128149
129- if ( loadResult . async ) {
150+ if ( loadResult . hasAsync ) {
130151 this . props . beginGlobalLoad ( ) ;
131- ( loadDataCounterOriginal => {
152+ ( ( loadDataCounterOriginal ) => {
132153 loadResult . promise . then ( ( ) => {
133154 // We need to change propsToShow only if loadAsyncData that called this promise
134155 // is the last invocation of loadAsyncData method. Otherwise we can face situation
@@ -146,7 +167,7 @@ class ReduxAsyncConnect extends React.Component {
146167 }
147168
148169 render ( ) {
149- const { propsToShow} = this . state ;
170+ const { propsToShow } = this . state ;
150171 return propsToShow && this . props . render ( propsToShow ) ;
151172 }
152173}
0 commit comments