43

使用 SSR 时出现以下错误

Warning: Expected server HTML to contain a matching <div> in <div>.

问题出在客户端上,在组件安装时检查浏览器宽度,然后设置组件的状态以呈现它的移动版本。

但是服务器默认容器的桌面版本,因为它不知道浏览器的宽度。

我该如何处理这种情况?我可以以某种方式检测服务器上的浏览器宽度并在发送到客户端之前渲染移动容器吗?

编辑:现在我决定在组件安装时渲染容器。这样,服务器端和客户端最初都不会渲染任何内容来阻止此错误。

我仍然愿意接受更好的解决方案

4

6 回答 6

28

这将解决问题。

// Fix: Expected server HTML to contain a matching <a> in
const renderMethod = module.hot ? ReactDOM.render : ReactDOM.hydrate;
renderMethod(
  <BrowserRouter>
    <RoutersController data={data} routes={routes} />
  </BrowserRouter>,
  document.getElementById('root')
);
于 2018-11-29T13:03:02.623 回答
19

盖茨比

gatsby的最新功能标志(在 2020 年 12 月v2.28中引入)能够在开发环境中进行服务器端渲染页面。

此标志true默认设置为。在这种情况下,您可能会在控制台中看到此错误消息

Warning: Expected server HTML to contain a matching <div> in <div>.

gatsby.config.js您可以在文件中禁用此标志:

module.exports = {
  flags: {
    DEV_SSR: false,
  }
}

文档:https ://www.gatsbyjs.com/docs/reference/release-notes/v2.28/#feature-flags-in-gatsby-configjs

于 2021-01-31T15:17:59.217 回答
4

当前接受的答案不适用于 TypeScript。这对我有用。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
  </body>
</html>
import React from "react"
import { hydrate, render } from "react-dom"
import BrowserRouter from "./routers/Browser"

const root = document.getElementById("root")
var renderMethod
if (root && root.innerHTML !== "") {
  renderMethod = hydrate
} else {
  renderMethod = render
}
renderMethod(<BrowserRouter />, document.getElementById("root"))
于 2020-03-29T09:36:09.530 回答
2

此消息也可能是由于错误代码无法在您的 SSR 和 CSR 之间呈现一致的内容,因此hydrate无法解决。

例如 SSR 返回:

...
<div id="root">
   <div id="myDiv">My div content</div>
</div>
...

当企业社会责任回归时:

...
<div id="root">
    <div id="anotherDiv">My other div content</div>
</div>
...

在这种情况下,最好的解决方案不是安装库或关闭,hydrate而是实际修复代码中的不一致。

暂时删除<script src="/react-bundle-path.js"></script>fromindex.js有助于比较 SSR 呈现的确切内容与 CSR 呈现的内容hydrate

于 2021-03-27T21:14:25.487 回答
1

HTTP 客户端提示可以帮助您解决这个问题。

另一篇关于客户端提示的有趣文章

于 2017-11-03T13:11:26.580 回答
0

我的解决方案是使用express-useragent之类的中间件来检测浏览器用户代理。

然后,在服务器端,按照以下规则创建一个viewsizelike{width, height}

if (ua.isMobile) {
  return {width: 360, height: 480}
}

if (ua.isDesktop) {
  return {width: 768, height: 600}
}

return {width: 360, height: 480} // default, and for bot

然后,它在某种程度上仍然是 SSR 中的响应式设计。

于 2018-05-03T05:28:59.130 回答