如何在expo-router中通过Link传递多个对象参数?
解决方案:Firestore筛选器对象跨页传递问题
首先你当前的URL参数写法有两个明显问题:
- 多个参数应该用
&分隔,而非多个? - 直接把对象拼进URL会变成
[object Object],必须先序列化为JSON字符串并编码,避免特殊字符干扰
一、修正URL参数传递方式
跳转时将两个对象序列化为JSON并编码:
import Link from 'next/link'; // 假设origin是目标页面路径 <Link href={`${origin}?listing=${encodeURIComponent(JSON.stringify(listing))}&property=${encodeURIComponent(JSON.stringify(property))}`} > 查看筛选结果 </Link>
二、目标页面接收参数
根据页面类型(客户端/服务器组件)选择对应的接收方式:
1. 客户端组件(Next.js App Router)
用useSearchParams钩子解析参数:
import { useSearchParams } from 'next/navigation'; export default function ResultsPage() { const searchParams = useSearchParams(); // 解码并解析回对象 const listing = searchParams.get('listing') ? JSON.parse(decodeURIComponent(searchParams.get('listing'))) : {}; const property = searchParams.get('property') ? JSON.parse(decodeURIComponent(searchParams.get('property'))) : {}; // 用这两个对象构建Firestore查询 // 例如:db.collection('listings').where(...) return <div>筛选结果页面</div>; }
2. 服务器组件(Next.js App Router)
通过searchParams props接收:
export default function ResultsPage({ searchParams }) { const listing = searchParams.listing ? JSON.parse(decodeURIComponent(searchParams.listing)) : {}; const property = searchParams.property ? JSON.parse(decodeURIComponent(searchParams.property)) : {}; // 服务器端构建Firestore查询 return <div>筛选结果页面</div>; }
三、更优实现方案
URL传递对象存在长度限制(不同浏览器URL长度上限不同),且如果筛选条件包含敏感数据会暴露在地址栏,推荐以下两种方案:
1. Next.js Link内置state传递(仅客户端组件适用)
跳转时将对象存在state属性中,不会暴露在URL:
import Link from 'next/link'; <Link href={origin} state={{ listing, property }} > 查看筛选结果 </Link>
目标页面客户端组件接收:
import { useRouter } from 'next/navigation'; export default function ResultsPage() { const router = useRouter(); const { listing = {}, property = {} } = router.state || {}; // 构建Firestore查询 return <div>筛选结果页面</div>; }
2. LocalStorage暂存(兼容所有页面类型)
跳转前将筛选条件存入LocalStorage,目标页面加载后读取:
// 跳转逻辑 const handleGoToResults = () => { localStorage.setItem('filterListing', JSON.stringify(listing)); localStorage.setItem('filterProperty', JSON.stringify(property)); window.location.href = origin; }; // 目标页面读取(客户端组件) import { useEffect, useState } from 'react'; export default function ResultsPage() { const [listing, setListing] = useState({}); const [property, setProperty] = useState({}); useEffect(() => { const savedListing = localStorage.getItem('filterListing'); const savedProperty = localStorage.getItem('filterProperty'); if (savedListing) setListing(JSON.parse(savedListing)); if (savedProperty) setProperty(JSON.parse(savedProperty)); // 读取后删除,避免残留 localStorage.removeItem('filterListing'); localStorage.removeItem('filterProperty'); }, []); // 构建Firestore查询 return <div>筛选结果页面</div>; }
方案选择建议
- 若目标是客户端组件,优先用Link state传递,简洁且无URL暴露问题
- 若目标是服务器组件,或需要支持用户通过URL分享筛选条件,用URL参数序列化传递
- 若筛选条件复杂、数据量大,用LocalStorage暂存
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

