Next.js登录仪表盘出现NotFoundError(removeChild)问题求助
解决Next.js中
NotFoundError: Failed to execute 'removeChild' on 'Node'错误 登录仪表盘时触发未处理运行时错误:NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node,刷新页面可正常进入,但返回登录页时错误重复出现,结合你提供的布局代码,可通过以下步骤修复:
1. 调整RootLayout的NoSsr包裹范围(核心修复)
你将所有内容包括LayoutProvider、ToastContainer和子组件都放在NoSsr中,这会破坏Next.js服务端渲染与客户端hydration的DOM一致性,导致路由切换时触发节点移除错误。
修改src/app/layout.js,仅将依赖浏览器API的组件(如OffCanvas)放入NoSsr:
import { Inter } from "next/font/google"; import "./globals.css"; import "bootstrap/dist/css/bootstrap.min.css"; import LayoutProvider from "./Provider"; import NoSsr from "@/utils/NoSsr"; import 'react-toastify/dist/ReactToastify.css'; import { ToastContainer } from "react-toastify"; import OffCanvas from "@/CommonComponent/Offcanvas"; const inter = Inter({ subsets: ["latin"] }); export default function RootLayout({ children }) { return ( <html lang="en"> <body className={inter.className}> <ToastContainer /> <LayoutProvider> {children} <NoSsr> <OffCanvas /> </NoSsr> </LayoutProvider> </body> </html> ); }
2. 替换Admin布局中的直接DOM操作
Admin布局里通过document.getElementById手动修改类名,可能在路由切换时DOM未完全卸载就执行操作,导致节点不匹配。改用React状态管理类名:
修改src/app/admin/layout.js:
"use client"; import './layout.css'; import '../../../public/assets/scss/style.scss'; import Sidebar from "@/components/Admin/Layouts/Sidebar"; import Header from "@/components/Admin/Layouts/Header/index"; import { useSelector } from 'react-redux'; import { useSearchParams } from 'next/navigation'; import { useEffect, useState } from 'react'; import { useSession } from 'next-auth/react'; const Layout = ({ children, className, ...rest }) => { const { sideBarType } = useSelector((store) => store.themeSlice); const backgroundColor = useSelector((store) => store.headerSlice.backGroundChange); const pathname = useSearchParams(); const { data: session, status } = useSession(); const router = useRouter(); const [isMobile, setIsMobile] = useState(false); // 处理窗口 resize,用状态记录移动端判断 useEffect(() => { const handleResize = () => setIsMobile(window.innerWidth < 992); window.addEventListener("resize", handleResize); handleResize(); return () => window.removeEventListener("resize", handleResize); }, []); // 计算pageWrapper类名,由React自动管理DOM const pageWrapperClasses = `${sideBarType} ${pathname.get("layout")} ${ isMobile || sideBarType !== "horizontal-wrapper" ? "compact-wrapper" : "horizontal-wrapper" }`; // 处理session加载与未登录状态 if (status === "loading") return <div>Loading...</div>; if (!session) { router.push("/login"); return null; } return ( <div id="mainLayout" className={`${backgroundColor}`}> <div className={`page-wrapper ${pageWrapperClasses}`} id="page-wrapper"> <Header /> <div className="page-body-wrapper horizontal-menu"> <Sidebar /> <div className="page-body">{children}</div> </div> </div> </div> ); }; export default Layout;
3. 检查OffCanvas组件的卸载逻辑
若OffCanvas内部有直接操作DOM的代码(如模态框的显示/隐藏),需确保组件卸载时清理所有DOM操作(如移除事件监听、临时DOM节点),避免路由切换时残留操作触发错误。
内容的提问来源于stack exchange,提问作者Aiswarya KV
相关产品推荐
相关产品推荐

