Next.js中use client与NextRouter及useState报错问题求助
Next.js App Router 中 NFT 详情页参数获取问题解决方案
问题描述
在Next.js项目的app/nft-details/page.tsx中遇到两个冲突问题:
- 添加
'use client'指令时,出现Error: NextRouter was not mounted错误 - 移除该指令后,触发
ReactServerComponentsError,提示:
You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
需求是通过<Link href={{ pathname: "nft-details", query: el}} key={i+1}>从搜索页传递参数到详情页,并在详情页接收参数展示NFT信息。
核心原因
你使用的是Next.js App Router(app/目录结构),但代码中误用了Pages Router专属的next/router钩子,这是导致路由未挂载错误的根本原因;同时组件依赖useState、useContext等客户端API,必须标记为客户端组件。
解决方案
1. 替换路由钩子
将next/router的useRouter替换为App Router专属的next/navigation中的useSearchParams。
2. 保留'use client'指令
组件使用了useState、useContext等仅在客户端运行的API,必须保留该指令标记为客户端组件。
3. 调整参数获取逻辑
通过useSearchParams获取URL参数并转换为对象。
修改后的完整代码
'use client'; import React, { useEffect, useState, useContext } from "react"; import { useSearchParams } from 'next/navigation'; // 替换为App Router的参数获取钩子 //INTERNAL IMPORT import { Button, Category, Brand } from "../../components/components-index"; import NFTDetailsPage from "../../NFTDetailsPage/NFTDetailsPage"; //IMPORT SMART CONTRACT DATA import { NFTMarketplaceContext } from "../../Context/NFTMarketplaceContext"; import Navbar from "../../components/Navbar/navbar"; import Footer from "../../components/Footer/footer"; const NFTDetails = () => { const { currentAccount } = useContext(NFTMarketplaceContext); const [nft, setNft] = useState({ image: "", tokenId: "", name: "", owner: "", price: "", seller: "", }); const searchParams = useSearchParams(); useEffect(() => { // 将URLSearchParams转换为普通对象 const nftParams = Object.fromEntries(searchParams.entries()); setNft(nftParams); }, [searchParams]); return ( <div> <Navbar/> <NFTDetailsPage nft={nft} /> <Category /> <Brand /> <Footer/> </div> ); }; export default NFTDetails;
补充说明
- App Router和Pages Router的路由API不兼容,
next/router仅适用于pages/目录,app/目录必须使用next/navigation提供的API useSearchParams返回的URLSearchParams对象,可通过entries()方法转换为键值对对象,直接赋值给状态即可- 若后续有路由跳转需求,App Router中应使用
next/navigation导出的useRouter,而非next/router
内容的提问来源于stack exchange,提问作者Iftikhar uddin
相关产品推荐
相关产品推荐

