2

背景

我正在开发一个基于反应的(MERN.io)项目(Eve's Temptation)。本项目的栈主要有 React、Redux、Webpack、Node 和 Express。在我实现服务器端渲染之后。我发现,在没有良好的网络连接的情况下,用户可以在一些渲染完成后看到全屏空白,然后重新渲染。所以它可能应该是一个重新渲染的问题。我在 MERN.io 上进行了测试,并在服务器端呈现的字符串中添加了一个额外的 div

从:

<div id="root">${html}</div>

至:

<div id="root"><div>${html}</div></div>

这可以解决

warning.js?8a56:33 警告:React 尝试在容器中重用标记,但校验和无效。这通常意味着您正在使用服务器渲染,并且在服务器上生成的标记不是客户端所期望的。React 注入了新的标记来补偿哪些工作,但您已经失去了服务器 > 渲染的许多好处。相反,找出为什么生成的标记在客户端或服务器上是不同的:

(client) <!-- react-empty: 1 -
(server) <div data-reactroot="

虽然我用这个方法解决了上面的问题,但是还是出现了白屏(客户端重新渲染)的问题。

在此处输入图像描述 在此处输入图像描述

这里我以代码 fromhttps://github.com/Hashnode/mern-starter为例,这是我们项目的基础。

客户端 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.js

请看https://github.com/Hashnode/mern-starter

=======这里是如何重现问题:=======

步骤1:

关闭生产模式的缩小,以便我们可以在浏览器中读取 js 代码并定位关键代码:

注释 webpack.config.prod.js 中的 UglifyJSPlugin(第 80~85 行):

  new ChunkManifestPlugin({
    filename: "chunk-manifest.json",
    manifestVariable: "webpackManifest",
  }),
  // new webpack.optimize.UglifyJsPlugin({
  //   compressor: {
  //     warnings: false,
  //   }
  // }),
],

第2步:

运行 mongodb 并在项目文件夹中运行npm run bs以运行产品模式

第 3 步:

在 Chrome 浏览器资源中,我们可以看到 js 文件app.cb4f935522b22f1d48a0.js,我们可以在 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);

第4步:

在 上设置断点(0, _reactDom.render)...,在运行这个函数之前,客户端已经用服务器端渲染的文档渲染了一些内容,在跨过这个函数之后,屏幕将是空白的。

在此处输入图像描述 在此处输入图像描述

我正在尝试找到一种解决方案来避免这种重新渲染,但这对我来说有点困难,

4

0 回答 0