3

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.

enter image description here enter image description here

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.

enter image description here enter image description here

I'm trying to find a solution to avoid this rerendering but It's kind of difficult for me,

Evan Zhou
  • 31
  • 3

0 Answers0