"React attempted to reuse markup" webpack + 代码拆分的错误



我已经开始在一个"通用"应用程序中实现代码拆分(react-router,redux,webpack - 主要基于 https://github.com/erikras/react-redux-universal-hot-example)。

在实现代码拆分的(唯一)路由上,我在执行完整的浏览器刷新时收到以下 React 错误消息:

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

如果我禁用代码拆分,错误消息就会消失。我猜这是由于 React 在 Webpack 加载器加载 Javascript 块之前进行了第一次渲染,因此,它生成的标记与服务器上生成的标记不同。这是对的吗?

  • 我应该担心错误消息吗?
  • 有什么方法可以弄清楚 React 在此消息发生的确切时间渲染到什么?
  • 有什么修复方法可以使消息消失吗?(除了不使用代码拆分)

解决方案是在执行第一次渲染之前调用 react router 的match函数。

查看 https://github.com/reactjs/react-router/issues/2036#issuecomment-225792937 和 https://github.com/reactjs/react-router/blob/v2.4.1/docs/guides/ServerRendering.md#async-routes

我应该担心错误消息吗?

是的,如果 React 确定标记不同,它将无法重用任何现有的标记,而是从客户端渲染重新生成它,从而为浏览器带来更多工作。

有什么方法可以弄清楚 React 在此消息发生的确切时间渲染到什么?

您可以通过区分开发工具中生成的源代码和通过网络发送的 html 来比较差异。

有什么修复方法可以使消息消失吗?(除了不使用代码拆分)

您可以按照答案中的建议调用match或者,如果您碰巧没有使用 React Router 或者您的拆分点没有通过路由器设置,您可以预先加载所有必需的块,例如

<!-- 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>

注意:这仅在使用require.ensure时有效,因为System.import/import始终是异步的,这意味着标记在第一次渲染时仍然会有所不同。

最新更新