NextJS 404页面报错:Objects are not valid as a React child
问题分析与解决方案
核心问题1:Async组件与客户端钩子冲突
你的NotFound组件是async函数,但useTranslations是客户端钩子,不能在服务器组件(async组件默认是服务器组件)中使用,这会触发React Suspense相关错误,也就是你看到的Expected a suspended thenable。
核心问题2:Button组件的onClick属性错误
你给Button的onClick传了字符串"/",但onClick需要接收函数类型的值,直接传字符串会导致React尝试渲染不符合要求的对象,触发Objects are not valid as a React child错误。
具体修复步骤
1. 将NotFound组件标记为客户端组件
在组件顶部添加'use client'指令,将其转为客户端组件,同时移除async关键字(客户端组件不能是异步函数):
'use client'; import Button from "@/components/buttons/button"; import { useTranslations } from 'next-intl'; import Image from "next/image"; /** * 404 Error Page * @returns React Node */ export default function NotFound() { const t = useTranslations('not-found'); return ( <div className="w-screen h-screen grid place-items-center"> <div className="-translate-y-6"> <Image className="w-80" src="/assets/images/cubes.svg" width={559} height={513} alt={t('images.cubes')} /> <h1 className="text-8xl w-[1000px] my-10"> {t('headings.not-found')} </h1> <Button onClick={() => window.location.href = '/'} background="yellow"> <h1 className="mt-1">{t('buttons.home')}</h1> </Button> </div> </div> ); }
2. 优化Button跳转逻辑(推荐)
如果使用Next.js App Router,更推荐用Link组件实现路由跳转,符合框架规范:
'use client'; import Button from "@/components/buttons/button"; import { useTranslations } from 'next-intl'; import Image from "next/image"; import Link from 'next/link'; export default function NotFound() { const t = useTranslations('not-found'); return ( <div className="w-screen h-screen grid place-items-center"> <div className="-translate-y-6"> <Image className="w-80" src="/assets/images/cubes.svg" width={559} height={513} alt={t('images.cubes')} /> <h1 className="text-8xl w-[1000px] my-10"> {t('headings.not-found')} </h1> <Link href="/" passHref> <Button background="yellow"> <h1 className="mt-1">{t('buttons.home')}</h1> </Button> </Link> </div> </div> ); }
3. 处理framer-motion的AnimatePresence冲突
如果布局中使用了AnimatePresence,可以通过判断路由路径,避免给错误页面包裹动画组件:
'use client'; import { AnimatePresence } from 'framer-motion'; import { useRouter } from 'next/navigation'; export default function RootLayout({ children }) { const router = useRouter(); const isErrorPage = router.state?.pathname === '/not-found'; return ( <html lang="en"> <body> {isErrorPage ? children : ( <AnimatePresence mode="wait"> {children} </AnimatePresence> )} </body> </html> ); }
验证要点
- 确认
not-found对应的翻译键在你的国际化配置文件中存在,避免翻译函数返回未定义值。 - 启动项目后,检查404页面渲染状态和按钮跳转功能是否正常。
内容的提问来源于stack exchange,提问作者PixelPage
相关产品推荐
相关产品推荐

