You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在expo-router中通过Link传递多个对象参数?

解决方案:Firestore筛选器对象跨页传递问题

首先你当前的URL参数写法有两个明显问题:

  1. 多个参数应该用&分隔,而非多个?
  2. 直接把对象拼进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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:45:26