diff --git a/modules/AsyncProps.js b/modules/AsyncProps.js
index 4c95c74..46e6c9f 100644
--- a/modules/AsyncProps.js
+++ b/modules/AsyncProps.js
@@ -8,6 +8,14 @@ function last(arr) {
return arr[arr.length - 1]
}
+/**
+ * We need to iterate over all components for specified routes.
+ * Components array can include objects if named components are used:
+ * https://github.com/rackt/react-router/blob/latest/docs/API.md#named-components
+ *
+ * @param components
+ * @param iterator
+ */
function eachComponents(components, iterator) {
for (var i = 0, l = components.length; i < l; i++) {
if (typeof components[i] === 'object') {
@@ -29,7 +37,11 @@ function filterAndFlattenComponents(components) {
return flattened
}
-function loadAsyncProps(components, params, cb) {
+function defaultResolver(Component, params, cb) {
+ Component.loadProps(params, cb)
+}
+
+function loadAsyncProps(components, params, cb, resolver = defaultResolver) {
// flatten the multi-component routes
let componentsArray = []
let propsArray = []
@@ -46,7 +58,7 @@ function loadAsyncProps(components, params, cb) {
}
components.forEach((Component, index) => {
- Component.loadProps(params, (error, props) => {
+ resolver(Component, params, (error, props) => {
needToLoadCounter--
propsArray[index] = props
componentsArray[index] = Component
@@ -112,7 +124,7 @@ function createElement(Component, props) {
return
}
-export function loadPropsOnServer({ components, params }, cb) {
+export function loadPropsOnServer({ components, params, resolver }, cb) {
loadAsyncProps(
filterAndFlattenComponents(components),
params,
@@ -125,7 +137,8 @@ export function loadPropsOnServer({ components, params }, cb) {
const scriptString = ``
cb(null, propsAndComponents, scriptString)
}
- }
+ },
+ resolver
)
}
@@ -189,6 +202,7 @@ class AsyncProps extends React.Component {
location: object.isRequired,
onError: func.isRequired,
renderLoading: func.isRequired,
+ resolver: func,
// server rendering
propsArray: array,
@@ -303,7 +317,8 @@ class AsyncProps extends React.Component {
prevProps: null
})
}
- })
+ }),
+ this.props.resolver
)
}
diff --git a/modules/__tests__/AsyncProps-test.js b/modules/__tests__/AsyncProps-test.js
index 3927aa8..2bdd0de 100644
--- a/modules/__tests__/AsyncProps-test.js
+++ b/modules/__tests__/AsyncProps-test.js
@@ -395,6 +395,33 @@ describe('AsyncProps', () => {
/>
), div, next)
})
+
+ it('allows to override resolver function', (done) => {
+ const appSpy = spyOn(App, 'loadProps').andCallThrough()
+
+ const next = execNext([
+ () => {},
+ () => {
+ expect(appSpy.calls.length).toEqual(1)
+ expect(appSpy.calls[0].arguments[2]).toEqual('check')
+ },
+ done
+ ])
+
+ function resolver(Component, params, cb) {
+ Component.loadProps(params, cb, 'check')
+ }
+
+ App.setAssertions(next)
+
+ render((
+ }
+ />
+ ), div, next)
+ })
})
describe('server rendering', () => {
@@ -420,6 +447,24 @@ describe('AsyncProps', () => {
})
})
+ it('allows to override resolver function', (done) => {
+ const appSpy = spyOn(App, 'loadProps').andCallThrough()
+ function resolver(Component, params, cb) {
+ Component.loadProps(params, cb, 'check')
+ }
+ const loadPropsRoutes = {
+ path: '/',
+ component: App
+ }
+ match({ routes: loadPropsRoutes, location: '/' }, (err, redirect, renderProps) => {
+ loadPropsOnServer({ ...renderProps, resolver }, () => {
+ expect(appSpy.calls.length).toEqual(1)
+ expect(appSpy.calls[0].arguments[2]).toEqual('check')
+ done()
+ })
+ })
+ })
+
it('renders synchronously with props from hydration', () => {
const html = renderToString(