React Router 传参三板斧:新手也能 5 秒做决定

前言

在单页应用里,路由跳转就像快递员把包裹送到另一个房间。包裹怎么装?地址怎么写?收件人怎么拆?每一步都决定包裹能否安全、准时、完整地送达。React Router 提供了三种最常用的"快递方式"------查询参数、路径参数和 state 隐式参数------它们各有优缺点、适用场景。

很多初学者容易混淆这三种方式:

  • 把本该公开分享的筛选条件写进了 state,结果刷新页面就"丢件";
  • 把只能临时使用的滚动位置写进了查询字符串,导致 URL 又丑又长;
  • 把对象直接塞进路径参数,结果浏览器直接 404。

本文带你快速掌握三种传参方式的核心差异。

一、 查询参数

① 路由声明

无需占位符,直接写静态路径。

js 复制代码
{ path: '/noteList', element: <NoteList /> }

② 路由跳转

声明式

js 复制代码
import { Link } from 'react-router-dom';

<Link to={{ pathname: '/noteList', search: '?category=1&page=2' }}>
  查看分类 1 第 2 页
</Link>

命令式

js 复制代码
import { useNavigate } from 'react-router-dom';

const navigate = useNavigate();
navigate({ pathname: '/noteList', search: '?category=1&page=2' });

search 必须是 '?key=value' 的完整字符串,也可以自己拼。

③ 路由接收:useSearchParams()

js 复制代码
import { useSearchParams } from 'react-router-dom';

function NoteList() {
  const [searchParams] = useSearchParams();
  const category = searchParams.get('category'); // "1"
  const page     = Number(searchParams.get('page')) || 1;
  return <>分类:{category} 第 {page} 页</>;
}

URL 上有 ?key=value,参数留在地址栏,刷新不丢 ,适合筛选、分页、排序。

二、路径参数

① 路由声明

在 path 中用冒号 : 占位。

js 复制代码
{ path: '/noteList/:category', element: <NoteList /> }

② 路由跳转

js 复制代码
<Link to="/noteList/123">分类 123</Link>
// 或
navigate('/noteList/123');

③ 路由接收: useParams()

js 复制代码
import { useParams } from 'react-router-dom';

function NoteList() {
  const { category } = useParams(); // "123"
  return <>当前分类 ID:{category}</>;
}

刷新页面,数据不丢失。

三、state 隐式参数

① 路由声明

任何路由都能接。

js 复制代码
{ path: '/noteList', element: <NoteList /> }

{ path: '/noteList/:category', element: <NoteList /> }

② 路由跳转

js 复制代码
// 命令式
navigate('/noteList', { state: { category: 1, from: 'banner' } });

// 声明式
<Link to="/noteList" state={{ category: 1 }} />

③ 路由接收: useLocation()

js 复制代码
import { useLocation } from 'react-router-dom';

function NoteList() {
  const { state } = useLocation();      // { category: 1, from: 'banner' }
  return <>来自:{state?.from}</>;
}

参数不会出现在 URL,刷新即消失 ,适合临时或一次性过渡数据(例如记住滚动位置)。

四、路由传参表

维度 查询参数(Query String) 路径参数(Path Params) 隐式参数(Location State)
URL 示例 /noteList?category=1&page=2 /noteList/1 /noteList(无痕迹)
路由声明 { path: '/noteList', element: <NoteList /> } { path: '/noteList/:category', element: <NoteList /> } { path: '/noteList', element: <NoteList /> }
跳转方式 navigate('/noteList?category=1') navigate('/noteList/1') navigate('/noteList', { state: { category: 1 } })
接收 Hook useSearchParams() 或 useLocation() + 手动解析 useParams() useLocation().state
数据类型限制 仅字符串 仅字符串 任意类型(对象、数组等)
刷新后保留 ✅ ✅ ❌
能否分享/收藏 ✅ ✅ ❌
URL 可读性 中(可能较长) 高(简洁明了) 最高(无参数痕迹)
典型场景 列表筛选、分页、搜索关键词 详情页 ID、RESTful 资源定位 临时过渡数据(如返回滚动位置、表单结果)
相关推荐
回眸&啤酒鸭41 分钟前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户69371750013841 小时前
2026,程序员的时代拐点到了
android·前端·后端
大龄秃头程序员1 小时前
一次 iBeacon + BLE 无感解锁方案的实现记录
前端
小兔子1 小时前
Python 的 GIL 与 free-threading:3.13 之后「去 GIL」走到哪一步了
前端
IT_陈寒1 小时前
SpringBoot自动配置差点让我加班到凌晨
前端·人工智能·后端
guslegend2 小时前
脚手架原理与本地调试:从 bin 软链接到 npm link
前端·npm·node.js·脚手架·前端工程化
海码事务所3 小时前
Google Play 新个人开发者账号上架指南:12 人连续 14 天封闭测试怎么做?
前端
田威AI3 小时前
图片内文字翻译的规格:输入输出、保真、自动化、时间与费用
前端·计算机视觉
不可能片场3 小时前
命令行中文变问号 我用环境变量救了场
前端·electron
lerhxx3 小时前
AI 应用中的上下文管理 —— 从"上下文窗口"到"分层压缩"的工程实践
前端·javascript