Next.js页面刷新时Query Props丢失的原因及解决办法
问题原因
as属性覆盖了实际Query参数:你在Link中设置的as={TvShows/?${title}}会将地址栏显示的URL替换为仅包含title的格式,而href里定义的result、img、index等参数并未被包含到as的URL中。刷新页面时,浏览器会根据地址栏的URL重新解析路由,此时router.query只能读取到title,其他参数自然丢失。- 复杂数据直接通过Query传递的局限性:
result是数组类型,直接放入Query会被自动序列化为字符串(比如[1,2,3]会变成"[1,2,3]"),刷新后解析时无法直接还原为原数组;另外Query参数有长度限制,传递复杂数据容易出现格式错误或数据截断。
修复方案
方案一:同步as与href的Query参数(适合简单数据传递)
如果一定要通过Query传递参数,需确保as的URL包含所有需要传递的参数,保证地址栏显示的内容与实际路由参数一致:
修改card.js中的Link:
<Link href={{ pathname: "/TvShows", query: { result: JSON.stringify(result), img: img, index: index, title: title } }} as={`/TvShows?title=${encodeURIComponent(title)}&result=${encodeURIComponent(JSON.stringify(result))}&img=${encodeURIComponent(img)}&index=${index}`} > {/* 链接内容 */} </Link>
修改TvShows.js解析参数:
const TvShows = () => { const [result, setResult] = useState([]); const [index, setIndex] = useState(""); const [img, setImg] = useState(""); const router = useRouter(); useEffect(()=>{ if(router.isReady){ // 反序列化数组参数 const parsedResult = router.query.result ? JSON.parse(decodeURIComponent(router.query.result)) : []; setResult(parsedResult); setIndex(router.query.index || ""); setImg(router.query.img || ""); } },[router.isReady]) return ( <div className=''> <Background result={result} img={img} index={index} /> </div> ) } export default TvShows
方案二:传递唯一标识,重新获取数据(推荐)
Query参数更适合传递简单标识,而非复杂数据。推荐传递数据的唯一ID(比如节目ID),在目标页面通过ID重新请求完整数据:
修改card.js(假设每个节目有id字段):
<Link href={{ pathname: "/TvShows", query: { id: result.id, title: title } }} as={`/TvShows?title=${encodeURIComponent(title)}&id=${result.id}`} > {/* 链接内容 */} </Link>
修改TvShows.js获取数据:
const TvShows = () => { const [result, setResult] = useState([]); const [img, setImg] = useState(""); const [index, setIndex] = useState(""); const router = useRouter(); useEffect(()=>{ if(router.isReady && router.query.id){ // 替换为实际获取数据的API请求 fetch(`/api/tv-shows/${router.query.id}`) .then(res => res.json()) .then(data => { setResult(data.result); setImg(data.img); setIndex(data.index); }) } },[router.isReady, router.query.id]) return ( <div className=''> <Background result={result} img={img} index={index} /> </div> ) } export default TvShows
额外说明
方案二更符合路由设计的最佳实践:Query参数不会暴露复杂数据,避免了长度限制和格式问题,同时能保证刷新页面后数据的一致性。
内容的提问来源于stack exchange,提问作者Mohammed Bekele
相关产品推荐
相关产品推荐

