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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:02:17