Skip to content

Instantly share code, notes, and snippets.

@simenbrekken
Created September 13, 2017 04:54
Show Gist options
  • Save simenbrekken/aaa8c978b30f4fc229ab3faec2892f5b to your computer and use it in GitHub Desktop.
Save simenbrekken/aaa8c978b30f4fc229ab3faec2892f5b to your computer and use it in GitHub Desktop.
Server-side rendering React applications with request resolver
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)
}
}
componentWillMount() {
registerRequestPromises(() => {
const queries = createQueries(mapPropsToQueries, this.props)
return this.dispatchQueries(queries)
})
}
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