Created
September 13, 2017 04:54
-
-
Save simenbrekken/aaa8c978b30f4fc229ab3faec2892f5b to your computer and use it in GitHub Desktop.
Server-side rendering React applications with request resolver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async (req, res, next) => { | |
const store = createStore() | |
const context = {} | |
const application = ( | |
<ReduxProvider store={store}> | |
<StaticRouter location={req.url} context={context}> | |
<Application /> | |
</StaticRouter> | |
</ReduxProvider> | |
) | |
try { | |
const markup = await resolveRequestPromises(() => renderToString(application)) | |
const { url, status } = context | |
if (url) { | |
res.redirect(302, url) | |
return | |
} | |
if (status) { | |
res.status(status) | |
} | |
res.send(renderDocument({ | |
state: store.getState(), | |
children: markup, | |
})) | |
} catch (error) { | |
next(error) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
componentWillMount() { | |
registerRequestPromises(() => { | |
const queries = createQueries(mapPropsToQueries, this.props) | |
return this.dispatchQueries(queries) | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let pendingPromises | |
let resolving = false | |
export const registerRequestPromises = createRequestPromises => { | |
if (resolving) { | |
const promises = createRequestPromises() | |
if (promises) { | |
pendingPromises.push(...promises) | |
} | |
} | |
} | |
const performIteration = async (resolver, iterations, maxIterations) => { | |
pendingPromises = [] | |
let result = resolver() | |
if (iterations < maxIterations && pendingPromises.length > 0) { | |
await Promise.all(pendingPromises) | |
result = performIteration(resolver, iterations + 1, maxIterations) | |
} | |
return result | |
} | |
export const resolveRequestPromises = async (resolver, { maxIterations = 1 } = {}) => { | |
resolving = true | |
const result = await performIteration(resolver, 0, maxIterations) | |
resolving = false | |
return result | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment