升级到 React 16 后,我收到此错误消息:
warning.js:33 Warning: Expected server HTML to contain a matching <div> in <body>.
通常是什么导致此错误消息以及如何修复?
升级到 React 16 后,我收到此错误消息:
warning.js:33 Warning: Expected server HTML to contain a matching <div> in <body>.
通常是什么导致此错误消息以及如何修复?
如果您使用ReactDOM.hydrate
启动 web 应用程序,您将看到此警告。
如果您的应用程序不使用服务器端渲染 ( ssr
),请使用ReactDOM.render
来启动。
如果您正在使用 NextJS 之类的服务器端渲染,请删除最近的代码并比较您是否尝试直接访问 DOM 尚不能保证的 Component 范围内的变量。对我来说,它是:
import { i18n } from 'i18n'
export default function SomeComponent() {
const initLanguage = i18n.language <---- causing error
return ...
}
如果您需要访问此类属性,请在 内访问它useEffect
,以确保到document
那时已经建立。它有点相当于componentDidMount()
:
import { i18n } from 'i18n'
import { useEffect, useState } from 'react'
export default function SomeComponent() {
const [initlanguage, setInitLanguage] = useState('en')
useEffect(() => setInitLanguage(i18n.language), [])
return ...
}
如果您的 HTML 代码类似于
<table>
<tr>
你会得到这个错误。
要绕过它,请使用 <tbody> 标签,例如
<table>
<tbody>
<tr>
不要忘记关闭标签!
这似乎是因为 Browsersync 在客户端的正文中插入了服务器端不存在的脚本标记。因此 React 无法附加到服务器渲染。
我通过尝试const searchParams = new URLSearchParams(process.browser ? window.location.search : '')
使用 material-ui SnackBar 在我的 NextJS 应用程序中的 react 组件的顶部使用 material UI 得到了这个,我能够通过将它放在一个useEffect
钩子中来消除错误。
整个组件供参考:
export default function SnackBarMessage() {
const [requestLogin, setRequestLogin] = useState(false)
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setRequestLogin(false)
}
useEffect(() => {
// had to move into a useEffect hook
const searchParams = new URLSearchParams(process.browser ? window.location.search : '')
const hasRequestLogin = Boolean(searchParams.get('requestLogin'))
if (hasRequestLogin) {
setRequestLogin(true)
}
}, [])
return (
<>
{requestLogin && (
<Snackbar open={requestLogin} autoHideDuration={6000} onClose={handleClose}>
<Alert onClose={handleClose} severity='error' style={{ fontSize: '18px' }} elevation={6}>
Please Log Back In
</Alert>
</Snackbar>
)}
</>
)
}