You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS中React Moralis的Notification Provider引发Hydration错误排查

Next.js Layout配置引发的Hydration错误及后续警告问题

问题背景

在FCC Pat Collins全栈开发课程第10课的Next.js项目中,配置layout.js后出现Hydration错误,导致开发无法推进。调整NotificationProvider的使用位置后错误消失,但出现新的属性警告。

初始代码

Layout.js

"use client"
import { Inter } from "next/font/google"
import "./globals.css"
import { MoralisProvider } from "react-moralis"
import { NotificationProvider } from "web3uikit"

const inter = Inter({ subsets: ["latin"] })

/* export const metadata = {
    title: "Smart Contract Lottery FCC",
    description: "Generated by create next app",
} */

export default function RootLayout({ children }) {
    return (
        <MoralisProvider initializeOnMount={false}>
            <NotificationProvider>
                <html lang="en">
                    <head>
                        <title>Smart Contract Lottery</title>
                    </head>
                    <body className={inter.className}>{children}</body>
                </html>
            </NotificationProvider>
        </MoralisProvider>
    )
}

page.js

"use client"
import { ConnectButton } from "web3uikit"
import LotteryEntrance from "../../components/LotteryEntrance"
export default function Home() {
    return (
        <main className="flex min-h-screen flex-col items-center justify-between p-48">
            <div className="max-w-2xl w-full items-center justify-between font-mono text-5xl">
                Smart Contract Lottery
            </div>
            <div className="flex flex-col gap-y-8 max-w-5xl justify-between items-center text-2xl p-12">
                Decentralized Lottery
                <ConnectButton moralisAuth={false} />
                <LotteryEntrance />
            </div>
        </main>
    )
}

初始错误信息

app-index.js:33 Warning: In HTML, <div> cannot be a child of <#document>.
This will cause a hydration error.
    at div
    at O2
    
    Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
    
    An error occurred during hydration. The server HTML was replaced with client content in <#document>.
    
    Uncaught DOMException: Failed to execute 'appendChild' on 'Node': Only one element on document allowed.
    
     Hydration failed because the initial UI does not match what was rendered on the server.
     
     There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
     
     Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
     
     The above error occurred in the <StrictMode> component:


Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

Uncaught AggregateError
    at flushSyncWorkAcrossRoots_impl 

尝试操作

将layout.js组件封装到单独文件再导入,问题依旧。

更新后的情况

调整NotificationProvider的使用方式,在page.js中用它包裹LotteryEntrance后,错误消失且UI可渲染,但出现以下警告:

app-index.js:33 Warning: Extra attributes from the server: data-new-gr-c-s-check-loaded,data-gr-ext-installed
    at body
    at html
    at MoralisProvider (

原因分析

  1. 初始Hydration错误原因:Next.js的RootLayout要求根元素必须是<html>,你将<MoralisProvider>和<NotificationProvider>放在了<html>外部。其中NotificationProvider会渲染一个<div>作为容器,这个<div>会成为document的直接子元素,违反HTML规范(document只能有一个根元素<html>),导致服务端渲染的HTML与客户端渲染的DOM结构不匹配,触发Hydration错误。

  2. 后续警告原因:data-new-gr-c-s-check-loaded和data-gr-ext-installed是第三方浏览器插件(如Grammarly)添加到<html>或<body>上的属性。服务端渲染的HTML中没有这些属性,客户端Hydration时检测到额外属性,因此发出警告。

解决办法

1. 修复Hydration错误

修改Layout.js,将<MoralisProvider>和<NotificationProvider>放在<body>内部,确保RootLayout的根元素是<html>:

"use client"
import { Inter } from "next/font/google"
import "./globals.css"
import { MoralisProvider } from "react-moralis"
import { NotificationProvider } from "web3uikit"

const inter = Inter({ subsets: ["latin"] })

export const metadata = {
    title: "Smart Contract Lottery FCC",
    description: "Generated by create next app",
}

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <head>
                <title>Smart Contract Lottery</title>
            </head>
            <body className={inter.className}>
                <MoralisProvider initializeOnMount={false}>
                    <NotificationProvider>
                        {children}
                    </NotificationProvider>
                </MoralisProvider>
            </body>
        </html>
    )
}

这样既符合Next.js的布局要求,也避免了非法的DOM结构。

2. 处理额外属性警告

  • 忽略警告:该警告由第三方插件引发,不影响项目功能,可直接忽略。
  • 抑制警告:在<html>标签上添加suppressHydrationWarning属性,抑制Hydration时的属性不匹配警告:
    <html lang="en" suppressHydrationWarning>
    
  • 排查插件:暂时禁用浏览器中的第三方插件(如Grammarly),确认警告是否消失。

内容的提问来源于stack exchange,提问作者tamermint

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 11:47:02