React/Next.js中Link href传递查询参数无法获取的解决方法
问题分析与解决方案
你的问题出在两个核心点:App Router 获取查询参数的方式错误,以及 Link 传递复杂对象参数的逻辑不符合 URL 规范。
错误点拆解
- App Router 不通过 router 对象暴露 query 参数
你使用的是 Next.js App Router 下的useRouter()(来自next/navigation),这个 router 对象本身不会直接显示查询参数,必须通过专门的useSearchParams()钩子来获取。 - 无法直接传递对象作为查询参数
Link 的href中直接传query: {post}无效,URL 查询参数仅支持字符串类型,对象无法被正确序列化为 URL 参数,导致参数直接丢失。
修复步骤
1. 修正 Dashboard 页面的 Link 组件
不要传递整个 post 对象,仅传递 post 的 id(这是更安全、高效且符合 URL 规范的做法):
// 替换你原来的Link代码 <Link href={`/post?id=${post.id}`}> <button className="text-teal-600 flex items-center justify-center gap-2 py-2 text-sm"> <AiFillEdit className="text-2xl" />Edit </button> </Link>
(注:你原来的 button 类名存在小错误:text-teal -600 多了空格,需改为 text-teal-600)
2. 在 /post 页面获取参数并加载数据
在目标页面 /post 中,通过 useSearchParams() 获取 id,再从 Firestore 查询对应数据:
"use client"; import { useSearchParams } from "next/navigation"; import { useEffect, useState } from "react"; import { doc, getDoc } from "firebase/firestore"; import { db } from "../../utils/firebase"; // 路径根据你的项目结构调整 export default function Post() { const searchParams = useSearchParams(); const postId = searchParams.get("id"); const [post, setPost] = useState(null); useEffect(() => { if (!postId) return; const fetchPost = async () => { const postRef = doc(db, "posts", postId); const postSnap = await getDoc(postRef); if (postSnap.exists()) { setPost({ ...postSnap.data(), id: postSnap.id }); } else { console.log("未找到对应文章"); } }; fetchPost(); }, [postId]); if (!post) return <div>加载中...</div>; return ( <div> {/* 渲染文章内容,示例如下 */} <h1>{post.title}</h1> <p>{post.content}</p> </div> ); }
补充方案(不推荐)
如果确实需要传递多个参数(不建议直接传整个对象),可以将对象序列化为 JSON 字符串后编码:
// Dashboard 页面的 Link <Link href={`/post?post=${encodeURIComponent(JSON.stringify(post))}`}> {/* 按钮内容 */} </Link> // /post 页面解析参数 const postStr = searchParams.get("post"); const post = postStr ? JSON.parse(decodeURIComponent(postStr)) : null;
但这种方式会让 URL 过长,且存在敏感数据泄露风险,所以优先推荐传递 id 再从数据库取数据的方案。
内容的提问来源于stack exchange,提问作者NoobCoder
相关产品推荐
相关产品推荐

