Olivier Lalonde
Olivier Lalonde

Reputation: 19928

"React attempted to reuse markup" error with webpack + code splitting

I've started implementing code splitting in an "universal" app (react-router, redux, webpack - largely based on https://github.com/erikras/react-redux-universal-hot-example).

On the (only) route where code splitting is implemented, I am getting the following React error message when doing a full browser refresh:

warning.js:44Warning: 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 class="root" dat

If I disable code splitting, the error message goes away. I am guessing this is due to React doing a first render before the Javascript chunk was loaded by the Webpack loader and therefore, it generates markup that is different from the one generated on the server. Is that correct?

Upvotes: 3

Views: 1035

Answers (2)

Richard Scarrott
Richard Scarrott

Reputation: 7063

Should I worry about the error message?

Yes, if React determines the mark-up differs it'll fail to re-use any of the existing mark-up and instead re-generate it from the client render resulting in more work for the browser.

Any way to figure out what React renders to at the exact time this message occurs?

You can compare the differences by diffing the generated source in dev tools and the html sent over the network.

Any fix to make the message go away? (other than to not use code splitting)

You could call match as you've suggested in your answer or alternatively, if you happen not to be using React Router or your split points aren't setup via the router you could load all required chunks up front, e.g.

<!-- index.html -->
<script src="entry.js"></script>
<script src="chunk1.js"></script>
<script>
    // NOTE: Instead of calling render immediately in `entry.js` you would need to define a function on the global to allow you to render the app after the second chunk has loaded.
    window.App.render();
</script>

NOTE: This would only work when using require.ensure because System.import / import is always async which would mean the mark-up would still differ on the very first render.

Upvotes: 0

Related Questions