Next.js:如何在getServerSideProps()中获取URL参数?useRouter报错‘router is not defined’问题解决
解决getServerSideProps中获取URL参数时的ReferenceError: router is not defined错误
你这个报错的原因很直接:useRouter是客户端React钩子,只能在组件内部使用,根本不能在服务端运行的getServerSideProps函数里调用。你在getServerSideProps里写router.query.slug,自然会提示router未定义。
正确的做法:用getServerSideProps的context参数拿路由参数
Next.js给getServerSideProps提供了一个context上下文对象,里面包含了所有服务端渲染时需要的请求信息,其中就包括动态路由参数和URL查询参数。我们直接从这个context里提取slug就行。
下面是修改后的完整代码:
import connectMongo from '../../utils/connectMongoos'; import Post from '../../models/postModel'; import MarkdownComponent from '../../components/utils/markdown'; // 接收Next.js传入的context参数 export const getServerSideProps = async (context) => { try { console.log('CONNECTING TO MONGO'); await connectMongo(); console.log('CONNECTED TO MONGO'); console.log('FETCHING DOCUMENTS'); // 从context.params里拿到动态路由的slug(对应你的[slug].js页面) const { slug } = context.params; const post = await Post.findOne({ slug }); console.log('FETCHED DOCUMENTS'); return { props: { data: JSON.parse(JSON.stringify(post)), }, }; } catch (error) { console.log(error); return { notFound: true, }; } }; export default function Posts({data}) { // 组件里如果用不到router可以直接删掉,不影响功能 // const router = useRouter() // const { slug } = router.query return( <div className="max-w-screen-md mx-auto font-inter m-2 p-4"> <MarkdownComponent text={data.markdown} /> </div> ) }
关键细节说明:
- 动态路由参数(比如
/post/my-first-post里的my-first-post)会存在context.params中,因为你的页面文件是[slug].js,所以直接解构context.params.slug即可 - 如果是URL查询参数(比如
/post?slug=my-first-post),则要从context.query.slug里获取 getServerSideProps是纯服务端运行的函数,不要在里面使用任何客户端专属的React钩子,比如useRouter、useState等
你之前遇到的错误:
ReferenceError: router is not defined at getServerSideProps (webpack-internal:///./pages/post/[slug].js:26:19) at runMicrotasks (<anonymous>)
本质就是混淆了服务端函数和客户端组件的API边界,记住这个边界就能避免类似问题。
内容的提问来源于stack exchange,提问作者Tesy Boy
相关产品推荐
相关产品推荐

