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

NextJS 14使用notistack 3.0.1触发enqueueSnackbar时出现NotFoundError

解决NextJS 14.0.4 + notistack 3.0.1 触发enqueueSnackbar时的removeChild错误

问题原因

这个错误是因为notistack的DOM挂载位置和NextJS的根节点结构冲突导致的。你的RootLayout把<Providers>放在了<html>标签外面,导致SnackbarProvider尝试操作不属于它管辖的DOM节点,卸载消息提示时就会出现「要移除的节点不是当前节点的子节点」的报错。

修复方案

1. 调整RootLayout的结构

把<Providers>移到<body>内部,让SnackbarProvider的上下文完全处于NextJS的根DOM节点(#__next)范围内:

const RootLayout = ({ children }: { children: React.ReactNode }) => {
    return (
        <html lang="no">
            <body id="__next">
                <Providers>
                    {children}
                </Providers>
            </body>
        </html>
    )
}

export default RootLayout

2. 可选:手动指定挂载容器

如果调整结构后问题仍存在,可以手动指定notistack挂载到#__next节点,避免DOM操作冲突:

"use client"

import { SnackbarProvider } from "notistack"
import { useEffect, useState } from "react"

export const Providers = ({ children }: { children: React.ReactNode }) => {
    const [container, setContainer] = useState<HTMLElement | null>(null)

    useEffect(() => {
        setContainer(document.getElementById("__next"))
    }, [])

    return (
        <SnackbarProvider container={container}>
             {children}
        </SnackbarProvider>         
    )
}

3. 规范enqueueSnackbar的调用

确保通过useSnackbar钩子获取enqueueSnackbar,且仅在客户端组件中调用:

"use client"
import { useSnackbar } from "notistack"

const MyComponent = () => {
    const { enqueueSnackbar } = useSnackbar()

    const handleSubmit = () => {
        enqueueSnackbar("操作成功", { variant: "success" })
    }

    return <button onClick={handleSubmit}>触发提示</button>
}

补充说明

NextJS的根布局中,<html>和<body>是框架控制的节点,把SnackbarProvider放在它们外面,会让消息提示元素挂载到错误的DOM层级。当提示要被移除时,React尝试从当前上下文的节点中删除它,但该节点实际属于更高层级的框架节点,最终抛出removeChild错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 00:52:37