【问题标题】:Warning: Expected server HTML to contain a matching <div> in <div>警告:预期的服务器 HTML 在 <div> 中包含匹配的 <div>
【发布时间】:2021-01-15 00:40:36
【问题描述】:

在我的 Next.js 应用程序中,我有一个 navbar ,它会根据用户是否登录显示不同的 UI。我决定通过读取 cookie 来跟踪用户是否登录。这是代码的相关部分:

export default function Navbar() {
  let loggedin
  if (typeof window !== undefined) {
    loggedin = getCookie('auth')
  }
  return (
   {!loggedin?
    // one UI logic
    :
   //different UI logic
  }
 )
}

getCookie 是一个使用 npm 包js-cookie 的简单函数:

export const getCookie = (name) => cookies.get(name)

我的问题是,当我重新加载页面或第一次加载页面时,我在控制台中收到此警告,并且 CSS 的某些部分已损坏:

react-dom.development.js:88 Warning: Expected server HTML to contain a matching <div> in <div>.
    in div (at Navbar.js:68)
    in div (at Navbar.js:67)
    in ul (at Navbar.js:34)
    in div (at Navbar.js:26)
    in nav (at Navbar.js:25)
    in Navbar (at Layout.js:12)
    in div (at Layout.js:11)
    in Layout (at pages/index.js:18)
    in Home (at _app.js:13)
    in UserProvider (at _app.js:13)
    in MyApp
    in ErrorBoundary (created by ReactDevOverlay)
    in ReactDevOverlay (created by Container)
    in Container (created by AppContainer)
    in AppContainer
    in Root

在我在客户端上导航到任何其他页面后,此警告不再出现,并且 CSS 已修复。我能够查明问题,如果我在代码中注释掉这部分,错误就消失了:

 if (typeof window !== undefined) {
    loggedin = getCookie('auth')
  }

当然,在这种情况下,我的导航栏逻辑被破坏了。我意识到服务器端没有 cookie,因此为了防止它在服务器上运行,如果 (typeof window !== undefined){} ,我会检查该行中代码的执行位置。但是,通过在 if 语句中添加console.log(),我可以看到它也在服务器上运行。

我做错了什么?为什么我会收到这个警告并且有一些损坏的 CSS?在这种情况下,为什么if statement 在服务器上运行?感谢您的帮助。

【问题讨论】:

  • 你为什么用这个? if (typeof window !== undefined)
  • @TasosBu 它是 nextjs 并且服务器端没有 window 对象。我只想在客户端上运行此代码,因此,这是对它的检查。
  • 哦,我明白了。难道没有更好的方法来检查它是在浏览器还是服务器上运行?
  • @TasosBu 我不这么认为
  • @Noob 作为旁注,typeof window !== undefined 将始终为真,因为typeof 返回一个字符串。如果您检查typeof window !== 'undefined',那么您将得到您正在寻找的结果(在浏览器中而不是服务器中执行)

标签: reactjs next.js


【解决方案1】:

如果您像这样将 cookie 检查放在 useEffect 中,我相信这将不需要:

import React, { useState } from 'react'

export default function Navbar() {
  const [loggedin, setLoggedin] = useState(false)

  useEffect(() => {
    const cookie = getCookie('auth')
    setLoggedin(cookie)
  }, [])
  
  return (
   {!loggedin?
    // one UI logic
    :
   //different UI logic
  }
 )
}

你能试一试,让我知道它是否有效吗?

【讨论】:

  • 是的,它可以工作,因为 useeffect 仅在客户端上运行。但是,我不明白我的代码发生了什么。
  • 我发现这篇文章可以回答你的问题:stackoverflow.com/a/53539693/5605822
猜你喜欢
  • 2020-07-04
  • 1970-01-01
  • 2021-08-11
  • 2021-08-19
  • 2021-09-05
  • 1970-01-01
  • 2021-08-16
  • 2018-03-08
  • 2020-11-07
相关资源
最近更新 更多