Next 13.3:如何使用NotFound()实现404页面
Next.js 13.3 动态路由触发404页面的正确实现方式
你遇到的核心问题是:notFound() 不能在客户端组件的 useEffect 中调用。这个函数是Next.js服务器端的API,只能在服务器组件的顶层或async函数的直接逻辑里使用,在客户端副作用里调用会导致环境不兼容的错误,自然无法触发404页面渲染。
正确实现方案
方案1:直接用服务器组件处理(推荐)
Next.js 13+ App Router下的页面默认是服务器组件,不需要加'use client',可以直接在async函数里获取数据并判断触发404,完全不需要useEffect和状态管理:
import { notFound } from 'next/navigation'; // 引入你的数据获取方法 import getPage from '@/utils/getPage'; export default async function Page({ params }) { const { slug } = params; const pageData = await getPage(slug); // 数据不存在时直接触发404 if (!pageData) { notFound(); } // 数据存在则直接渲染内容 return ( <div> <h1>{pageData.title}</h1> <div>{pageData.content}</div> </div> ); }
方案2:如果需要客户端交互逻辑
如果页面必须用客户端组件(比如需要状态、交互事件),可以拆分逻辑:在服务器组件里先完成数据校验和404触发,再把数据传给客户端组件:
- 服务器组件
page.jsx:
import { notFound } from 'next/navigation'; import getPage from '@/utils/getPage'; // 引入客户端组件 import ClientPage from './ClientPage'; export default async function Page({ params }) { const { slug } = params; const pageData = await getPage(slug); if (!pageData) { notFound(); } return <ClientPage pageData={pageData} />; }
- 客户端组件
ClientPage.jsx:
'use client'; import { useState } from 'react'; export default function ClientPage({ pageData }) { // 这里可以添加客户端需要的状态和交互逻辑 const [isExpanded, setIsExpanded] = useState(false); return ( <div> <h1>{pageData.title}</h1> <button onClick={() => setIsExpanded(!isExpanded)}> {isExpanded ? '收起' : '展开'}内容 </button> {isExpanded && <div>{pageData.content}</div>} </div> ); }
关键注意点
- 确保你的项目中存在
not-found.jsx文件,可以放在根目录app/下(全局生效),或者放在[slug]/目录下(仅该路由生效):
// app/not-found.jsx export default function NotFound() { return ( <div style={{ padding: '2rem', textAlign: 'center' }}> <h1>404 - 页面不存在</h1> <p>你访问的页面无法找到,请检查路径是否正确</p> </div> ); }
- 不要在客户端的副作用(
useEffect)、事件处理函数里调用notFound(),这类场景下Next.js客户端环境无法识别该函数的逻辑,只会抛出错误。
内容的提问来源于stack exchange,提问作者Nick Wild
相关产品推荐
相关产品推荐

