2

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!

Aren Hovsepyan
  • 1,598
  • 2
  • 11
  • 37

2 Answers2

1

The behavior you are reporting sounds irregular.

Are you using any webpack plugin to remove warnings from your console?

In order to find out what happened i would start from debugging the canReuseMarkup function inside react's ReactMount.js to find if the checksum generated from the client is similar to the one generated on the server.

The reason for no checksum showing after the rerender as mentioned by Charlie Marsh in here:

If you inspect a React component that's been rendered on the server (i.e., generated with renderComponentToString), you'll notice that it has an unfamiliar attribute, data-react-checksum, which you won't have seen on client-side components. Stepping one level deeper into the addChecksumToMarkup function reveals that data-react-checksum is an Adler-32 checksum generated from the HTML markup and appended to any component rendered server-side.

Matan Bobi
  • 2,185
  • 13
  • 24
  • on my dev env there is no any plugin for removing warnings, also I got one time that warning about checksum, so I know how it looks like, but somehow it doesn't show warnings now :) – Aren Hovsepyan Mar 03 '17 at 07:07
  • Did you try to debug the `canReuseMarkup` function in order to see if the checksum generated is the same? – Matan Bobi Mar 03 '17 at 18:33
  • Hi @Matan Bobi, looked at `canReuseMarkup`, so if I wrap my server string into `
    ` it can't find checksum to connect DOM, but if I don't wrap like I mentioned in last update it can find checksum, but somehow clients output is `` which of course diffs from server side normal output. If you could help me I would be very thankful, what can I provide you to look at it? Thanks in advance!
    – Aren Hovsepyan Mar 04 '17 at 06:40
  • are you using the same routes on server and on client? can you upload the components you are trying to render? Try and render a simple div with text on both sides and check what happens and then add component by component to see what messes it up – Matan Bobi Mar 05 '17 at 10:14
1

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')
    )
})
donut
  • 9,157
  • 5
  • 29
  • 52
Aren Hovsepyan
  • 1,598
  • 2
  • 11
  • 37