setSearchParams 完整教程(React Router v6,适配 React19)
一、基础介绍
jsx
import { useSearchParams } from 'react-router-dom'
// 解构:searchParams读取参数,setSearchParams修改URL查询参数
const [searchParams, setSearchParams] = useSearchParams()
作用:原地修改当前页面 ? 后的查询参数,不跳转新页面,组件自动重渲染
- 自动编码中文/特殊符号(不用手动
encodeURIComponent) - 读取时自动解码(不用
decodeURIComponent) - 对比
navigate('/?xxx'):navigate会新增历史记录;setSearchParams可选择替换历史
二、5种传参写法
1. 传对象(最常用,简单场景)
直接传键值对,会完全覆盖原有所有参数
jsx
// URL 变为 /?if_login=true&name=朝阳
setSearchParams({
if_login: 'true',
name: '测试&首页' // 内部自动编码
})
2. 回调函数写法(保留原有参数,分页/筛选必备)
重点!直接传对象会清空旧参数;用回调可以基于当前参数修改、保留其他参数
jsx
// 当前URL:/?if_login=true&sort=price
setSearchParams(prev => {
// prev 是原始 searchParams 对象(URLSearchParams)
prev.set('page', '2') // 新增/修改page,保留if_login、sort
prev.set('name', '朝阳')
return prev
})
// 结果:/?if_login=true&sort=price&page=2&name=%E6%9C%9D%E9%98%B3
常用操作:
jsx
setSearchParams(prev => {
prev.set('page', 1) // 修改
prev.delete('sort') // 删除某个参数
return prev
})
3. 传 URLSearchParams 实例
适合复杂多参数批量处理
jsx
const params = new URLSearchParams()
params.set('if_login', 'true')
params.set('name', '朝阳')
setSearchParams(params)
4. 传查询字符串
jsx
setSearchParams("if_login=true&name=朝阳")
setSearchParams("?if_login=true&name=朝阳") // 带?也兼容
5. 传二维数组(支持同一个key多个值)
jsx
setSearchParams([
['page', '1'],
['tag', 'react'],
['tag', 'router']
])
// ?page=1&tag=react&tag=router
三、第二个配置参数 { replace: true }
默认:修改参数会新增一条历史记录 ,点返回会回到上一个参数状态
replace: true:替换当前历史记录,回退直接跳上一页(分页、筛选推荐)
jsx
// 替换模式,不增加历史栈
setSearchParams({ page: 3 }, { replace: true })
// 回调搭配replace
setSearchParams(prev => {
prev.set('page', 3)
return prev
}, { replace: true })
四、实战完整示例(贴合你之前的 name=朝阳 案例)
jsx
import { useSearchParams } from 'react-router-dom'
export default function Page() {
const [searchParams, setSearchParams] = useSearchParams()
// 读取参数,自动解码
const name = searchParams.get('name')
const isLogin = searchParams.get('if_login')
// 按钮修改参数(保留原有其他参数)
const updateQuery = () => {
setSearchParams(prev => {
prev.set('if_login', 'true')
prev.set('name', '测试&首页') // 自动编码特殊符号
return prev
}, { replace: true })
}
// 清空所有参数
const clearQuery = () => setSearchParams({})
return (
<div>
<p>name参数:{name}</p>
<button onClick={updateQuery}>设置参数 if_login & name</button>
<button onClick={clearQuery}>清空所有查询参数</button>
</div>
)
}
五、核心坑点(必看)
坑1:直接传对象会清空全部旧参数
jsx
// 当前地址 ?a=1&b=2
setSearchParams({ c: 3 })
// 结果:?c=3 a、b直接消失!
✅ 解决:用回调函数 (prev) => {} 操作原有参数
坑2、编解码完全内置,无需手动处理
- 写入:
setSearchParams自动encodeURIComponent - 读取:
searchParams.get()/Object.fromEntries(searchParams)自动解码
不要额外套 encode/decode,会出现双重转义bug
坑3、所有值最终都会转为字符串
数字、布尔传入会变成字符串:
jsx
setSearchParams({ page: 2 })
searchParams.get('page') // "2" 字符串,不是数字
坑4、删除参数方式
jsx
// 方式1:回调delete(推荐,保留其他参数)
setSearchParams(prev => {
prev.delete('name')
return prev
})
// 方式2:重新传对象覆盖(会清空其他参数)
setSearchParams({ if_login: 'true' })
六、对比 navigate 修改参数
navigate(/?page=2)- 完整跳转,新增历史记录
- 必须手动拼接字符串,自己处理编码
setSearchParams({page:2})- 原地更新URL,组件刷新
- 内置编解码,可保留旧参数、可替换历史
分页、筛选、搜索框联动优先用 setSearchParams
七、配合 Object.fromEntries 一键获取所有参数
jsx
const [searchParams] = useSearchParams()
const query = Object.fromEntries(searchParams)
console.log(query.name, query.if_login)
内部自动解码,直接拿到原始文本。