Skip to content

Commit 3a0c4c2

Browse files
author
Andres Gutierrez
committed
Be more explicit in the way we declare deferred data
1 parent 4887652 commit 3a0c4c2

File tree

2 files changed

+56
-27
lines changed

2 files changed

+56
-27
lines changed

modules/ReduxAsyncConnect.js

+44-23
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const { array, func, object, any } = React.PropTypes;
1616
function 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

6375
export 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
}

modules/asyncConnect.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ export const LOAD_FAIL = 'reduxAsyncConnect/LOAD_FAIL';
66
export const CLEAR = 'reduxAsyncConnect/CLEAR';
77
export const BEGIN_GLOBAL_LOAD = 'reduxAsyncConnect/BEGIN_GLOBAL_LOAD';
88
export const END_GLOBAL_LOAD = 'reduxAsyncConnect/END_GLOBAL_LOAD';
9+
const initialState = {
10+
loaded: false,
11+
deferredLoaded: true,
12+
};
913

10-
export function reducer(state = {loaded: false}, action = {}) {
14+
export function reducer(state = initialState, action = {}) {
1115
switch (action.type) {
1216
case BEGIN_GLOBAL_LOAD:
1317
return {
@@ -17,7 +21,8 @@ export function reducer(state = {loaded: false}, action = {}) {
1721
case END_GLOBAL_LOAD:
1822
return {
1923
...state,
20-
loaded: true
24+
loaded: true,
25+
deferredLoaded: !action.loadDeferred,
2126
};
2227
case LOAD:
2328
return {
@@ -81,8 +86,11 @@ export function beginGlobalLoad() {
8186
return { type: BEGIN_GLOBAL_LOAD };
8287
}
8388

84-
export function endGlobalLoad() {
85-
return { type: END_GLOBAL_LOAD };
89+
export function endGlobalLoad(loadDeferred = false) {
90+
return {
91+
type: END_GLOBAL_LOAD,
92+
loadDeferred: loadDeferred,
93+
};
8694
}
8795

8896
function load(key) {

0 commit comments

Comments
 (0)