Server Side Rendering (Universal)
See original GitHub issueDo sagas handle server side rendering?
When on the server, there is a need to adapt async code into a synchronous flow, as we are handling a blocking server request that is waiting on some sort of data. If we’re using React, we need to call ReactDOM.renderToString
after we have our redux state populated. Often times that state is sourced from async sources, such as a REST API. So, we have to resolve those asynchronous processes back in the flow of the request.
I currently use Promises (and some custom data fetching dectorators) to handle this:
Promise.all(
prefetchData(components, store)
).then(render);
That’s a simplified form, but it’s basically the same thing. My component decorator defines certain actions to send through Redux when calling prefetchData
on it. It gets the promises from those actions (I use redux-promise
currently) and bundles them up with Promise.all
to let them be resolved before rendering.
Now, given a relatively complex saga, it looks like there isn’t a sole promise to resolve. Is there, instead, some way we could watch for the completion of a set of sagas? That is, I could continue to dispatch my actions from my component decorators, followed by some call to the saga runner to wait for the generator functions we’ve invoked from those actions to finish. If so, I can use that as a means to get back to my synchronous flow and return a response to my blocking server request.
Issue Analytics
- State:
- Created 8 years ago
- Reactions:15
- Comments:48 (31 by maintainers)
Top GitHub Comments
In my opinion it would be perfect if components don’t even know about sagas existence. Components should operate only with actions. But i can’t figure out an appropriate way how can we distinguish on the server the moment when all sagas are done. I mean, we can register all sagas on the server like we do on the client, then emit actions to run them, but when to render? I will appreciate if someone can come up with ideas or with ready to use solution 😃
I’ve just committed the approximate solution. If you disable JavaScript in the browser you will clearly see that server return page with necessary data:
DevTools has been disabled (see file ./containers/Root.dev.js) since there is an error around it:
It’s not that obvious how to fix it. I would ask @gaearon as an author of these dev tools for an advise.