React 16:警告:由于状态,预期服务器 HTML 在 <div> 中包含匹配的 <div>

React 16: Warning: Expected server HTML to contain a matching <div> in <div> due to State

我在使用 SSR 时遇到以下错误

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

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

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

遇到这种情况怎么办?我能否以某种方式检测服务器上的浏览器宽度并在发送到客户端之前呈现移动容器?

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

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

HTTP Client Hints 可以帮助您。

Another interesting article regarding Client Hints.

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

然后,在服务器端,通过以下规则创建一个viewsize like {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中的响应式设计

这将解决问题。

// 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')
);

当前接受的答案不适用于 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"))

盖茨比

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

此标志默认设置为 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

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

例如SSR returns :

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

虽然企业社会责任 returns :

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

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

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

呈现的内容