Search code examples
reactjswebpackreduxlazy-loadingserver-side

React server side rendering and lazy loading of webpack


I am using server side rendering with lazy loading of Webpack 2.2.0 using import() method, and using babel-plugin-transform-ensure-ignore for server side only, everything runs without errors and perfectly working except one thing. when page is loaded I can see server side rendering, but when webpack calling my dynamic component, all page renders again, which is visible for users. I need to know how to handle such problems. I found it when saw that, my first line is

<div data-reactroot="" data-reactid="1" data-react-checksum="-1269702275">

but when my lazy loaded components are parsed and executed whole content of my react root element removed and rendered again and my first element is <div data-reactroot>

Hope someone can help me.

Thanks in advance!

NOTE

There is no react warning about checksum.

UPDATE 2/4/2017

here is my markup for app

<div id="app">
    <div>
        <%- body %>
    </div>
</div>

div with id app is my react application container

UPDATE 3/4/2017

after I changed my markup to

<div id="app"><%- body %></div>

finally react on client found checksum, but I got this error.

React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:

(client) <!-- react-empty: 1 -

(server) <div data-reactroot="

My client root element is

<Provider store={store}>
    <Router history={history} routes={routes} onUpdate={() => window.scrollTo(0, 0)}/>
</Provider>

and server is

<Provider store={store}>
    <RouterContext {...renderProps} />
</Provider>

which I think should generate same code!


Solution

  • After debugging I found issue which was connected with React Router. so Router element renders <!-- react empty --> if app using lazy loading with import, that's why my checksum of server side was mismatching.

    So following to this example I fixed issue, with re-rendering. now my code looks like this.

    match({ history, routes }, (error, redirectLocation, renderProps) => {
        ReactDOM.render(
               <Provider store={store}>
                    <Router {...renderProps} />
               </Provider>, document.getElementById('app')
        )
    })