Expo Router push方法忽略encodeURIComponent编码问题求助
问题重现
你的代码中,原始参数值为 "foo 2%",经 encodeURIComponent 编码后得到 "foo%20%25",但通过 router.push 跳转至 /recipe 页面后,使用 useLocalSearchParams 获取到的 name 仍为未编码的 "foo 2%",导致后续解码操作报错崩溃。
另外注意你的代码存在语法错误:router.push 的模板字符串末尾多了多余的 )},正确写法应为:
router.push(`/recipe?name=${encodedName}`)
原因分析
Expo Router 的 router.push 在处理 URL 字符串时,会自动对参数进行解码操作;同时 useLocalSearchParams 返回的也是已经解码后的参数值。因此你手动编码后传递的参数,会被路由自动解码回原始值,导致预期的编码状态丢失。如果此时在目标页面再次调用 decodeURIComponent,就会因为原始值中的 % 被当成不完整的 URI 编码片段而报错。
解决办法
方案1:利用路由自动编码/解码,无需手动处理
直接传递原始参数值,Expo Router 会自动完成 URL 编码和解码流程,避免手动编码导致的冲突:
const { name } = foo; // "foo 2%" // 无需手动编码,直接传递原始值 router.push(`/recipe?name=${name}`);
在目标页面直接使用 useLocalSearchParams 返回的参数即可,不需要额外解码:
import { useLocalSearchParams } from 'expo-router'; export default function RecipePage() { const { name } = useLocalSearchParams(); // 直接使用 name,值为 "foo 2%" return <div>{name}</div>; }
方案2:双重编码保留编码状态(若需后端处理编码值)
如果必须在目标页面保留编码后的字符串(比如需要传递给后端接口),可以对参数进行双重编码:
const { name } = foo; const doubleEncodedName = encodeURIComponent(encodeURIComponent(name)); router.push(`/recipe?name=${doubleEncodedName}`);
在目标页面先解码一次得到原本的编码值,再按需二次解码:
const { name } = useLocalSearchParams(); const encodedName = decodeURIComponent(name); // 得到 "foo%20%25" const decodedName = decodeURIComponent(encodedName); // 得到 "foo 2%"
方案3:使用对象形式传递参数(避免URL编码)
使用 router.push 的对象参数形式,参数会通过路由状态传递,不经过URL编码解码流程:
router.push({ pathname: '/recipe', params: { name: name }, });
目标页面同样通过 useLocalSearchParams 获取参数,值为原始的 "foo 2%"。
内容的提问来源于stack exchange,提问作者Marc Fletcher

