davnicwil / react-frontload

Async data loading for React components, on client & server
451 stars 21 forks source link

server rendering does not work on 1.0.5 #27

Closed jtorjo closed 5 years ago

jtorjo commented 5 years ago
import React from 'react';
import { renderToString } from 'react-dom/server';
import Helmet from 'react-helmet';
import { Provider } from 'react-redux';
import { StaticRouter } from 'react-router';
import { Frontload, frontloadServerRender } from 'react-frontload';
import Loadable from 'react-loadable';

....
            .then( ss =>
                  frontloadServerRender(() => {
                        renderToString(
                          <Loadable.Capture report={m => modules.push(m)}>
                            <Provider store={store}>
                              <StaticRouter location={req.url} context={context}>
                                <Frontload isServer>
                                  <App />
                                </Frontload>
                              </StaticRouter>
                            </Provider>
                          </Loadable.Capture>
                        );
                    }
                  )
            )

This works on 1.0.1, but fails on 1.0.5 with:

(node:9936) UnhandledPromiseRejectionWarning: TypeError: asyncResource.runInAsyncScope is not a function at withAsyncContext ...\web\node_modules\react-frontload\lib\index.js:64:24) at frontloadServerRender (....\web\node_modules\react-frontload\lib\index.js:274:10) at ..../web/server/loader.js:209:19 at at process._tickCallback (internal/process/next_tick.js:188:7) (node:9936) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

davnicwil commented 5 years ago

Thanks, this is the same issue as #23.

Basically, it requires node 8.12.0 or above. Not ideal as it should work with 8.0.0 and above, but if you can bump your node version up that far, it will fix it.

Hope to get a fix out very soon, if it's possible.

jtorjo commented 5 years ago

Thanks! Unfortunately I'm locked on the node version - I have 8.11.3 (on a docker container), and I can't change it at this time. Looking forward to the fix!

davnicwil commented 5 years ago

So, it's not good news I'm afraid.

I've investigated and, yes, turns out the specific APIs I'm using to automagically isolate render context to each request were introduced in 8.12.0 -- that means unfortunately there's no easy fix I can see to make it work with any earlier version.

There is a more manual way, that was actually introduced in v1.0.4 but then removed again, where the render function inside frontloadServerRender is passed a second argument context which you then need to manually pass as a prop to the Frontload provider. The full docs for this are in the commit history here

I think I'm going to have to bring back this API, to support versions of node below 8.12.0 -- it's uglier, but it works. And eventually when more people can upgrade node past 8.12.0, it can go away.

For now though, you can just use v1.0.4, it should work fine for you. Let me know here if this works for you and I'll close the issue 👍

davnicwil commented 5 years ago

v1.0.6 is shipped, now all versions of node are supported but you have to make minor changes to your server render code if using node < 8.12.0

Please read the new documentation in the README for more info