Background
I'm working on a react based (MERN.io) project( Eve's Temptation ). This project's stacks are mainly React, Redux, Webpack, Node and Express. After my implementation of server-side rendering. I found that, with no good network connection, a user can see a full-screen blank after some rendering finishes, then it re-renders. So it probably should be a re-render issue. I tested on MERN.io and add an extra div in server-side rendered string
From:
<div id="root">${html}</div>
To:
<div id="root"><div>${html}</div></div>
This can solve the
warning.js?8a56:33 Warning: 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="
Although I used this method to solve the issue above, the white screen ( client re-rendering ) issue occurs.
Here I use code from https://github.com/Hashnode/mern-starter
as an example, which is our project based on.
Client index.js:
/**
* Client entry point
*/
import React from 'react';
import { render } from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import App from './App';
import { configureStore } from './store';
// Initialize store
const store = configureStore(window.__INITIAL_STATE__);
const mountApp = document.getElementById('root');
render(
<AppContainer>
<App store={store} />
</AppContainer>,
mountApp
);
// For hot reloading of react components
if (module.hot) {
module.hot.accept('./App', () => {
// If you use Webpack 2 in ES modules mode, you can
// use <App /> here rather than require() a <NextApp />.
const NextApp = require('./App').default; // eslint-disable-line
global-require
render(
<AppContainer>
<NextApp store={store} />
</AppContainer>,
mountApp
);
});
}
Server: server.js
please see it on https://github.com/Hashnode/mern-starter
======= HERE ARE HOW TO REPRODUCE THE ISSUE: =======
Step 1:
Turn off the minification on production mode so that we can read the js code in browser and target the critical code:
comment the UglifyJSPlugin in webpack.config.prod.js ( line 80~85):
new ChunkManifestPlugin({
filename: "chunk-manifest.json",
manifestVariable: "webpackManifest",
}),
// new webpack.optimize.UglifyJsPlugin({
// compressor: {
// warnings: false,
// }
// }),
],
Step 2:
Run mongodb and in the project folder run npm run bs
to run product mode
Step 3:
In Chrome browser resources, we can see js file like app.cb4f935522b22f1d48a0.js
, we can find the code near line 10316
// Initialize store
var store = (0, _store.configureStore)(window.__INITIAL_STATE__);
var mountApp = document.getElementById('root');
(0, _reactDom.render)(_jsx(_reactHotLoader.AppContainer, {}, void 0, _jsx(_App2.default, {
store: store
})), mountApp);
Step 4:
Set a breakpoint on (0, _reactDom.render)...
, before running this function, client-side already rendered some content with a server-side rendered document, after stepping over this function, the screen will be blank white.
I'm trying to find a solution to avoid this rerendering but It's kind of difficult for me,