react中路由跳转时传参方式
React中路由跳转时传参方式详解
导语
在React应用开发中,路由管理是构建单页面应用(SPA)的核心环节。而路由间的参数传递则是实现页面间数据共享的关键技术。本文将全面剖析React路由跳转时的各种传参方式,帮助开发者根据不同场景选择最合适的方案。
核心概念解释
React路由传参主要涉及两种主流路由库:
1. React-Router v5及以下版本:主要通过history
对象操作
2. React-Router v6:采用新的Hooks API设计
无论哪种版本,常见的传参方式都可以归类为以下几种: - URL参数(Params) - 查询参数(Query) - 状态参数(State) - 动态路由参数
使用场景与实现方式
1. URL参数(Params)
适用场景:参数是资源标识符(如ID)、需要SEO友好、参数简单且必要
// React-Router v5
// 定义路由
<Route path="/user/:id" component={User} />
// 跳转时
this.props.history.push('/user/123');
// 获取参数
this.props.match.params.id; // '123'
// React-Router v6
// 定义路由
<Route path="/user/:id" element={<User />} />
// 跳转时
navigate('/user/123');
// 获取参数
const { id } = useParams();
2. 查询参数(Query)
适用场景:参数可选、参数较多、需要保留在URL中但非核心标识
// React-Router v5
import qs from 'query-string';
// 跳转时
this.props.history.push({
pathname: '/search',
search: qs.stringify({ q: 'react', page: 1 })
});
// 获取参数
const query = qs.parse(this.props.location.search);
// React-Router v6
import { useSearchParams } from 'react-router-dom';
function SearchPage() {
const [searchParams] = useSearchParams();
const query = searchParams.get('q');
const page = searchParams.get('page');
// ...
}
3. 状态参数(State)
适用场景:传递复杂对象、敏感数据、临时状态
// React-Router v5
// 跳转时
this.props.history.push('/profile', {
user: { name: 'John', age: 30 }
});
// 获取参数
this.props.location.state?.user;
// React-Router v6
// 跳转时
navigate('/profile', {
state: { user: { name: 'John', age: 30 } }
});
// 获取参数
const { state } = useLocation();
const user = state?.user;
4. 动态路由参数
适用场景:参数结构复杂、需要灵活匹配
// React-Router v6
<Route
path="/blog/:year/:month/:day/:slug"
element={<BlogPost />}
/>
// 跳转时
navigate('/blog/2023/05/15/react-routing');
// 获取参数
const { year, month, day, slug } = useParams();
优缺点对比
传参方式 | 优点 | 缺点 |
---|---|---|
URL参数 | SEO友好,可分享链接 | 只能传递字符串,暴露在URL中 |
查询参数 | 灵活,可传递多个参数 | URL冗长,需要解析库 |
状态参数 | 可传递复杂对象,不暴露在URL | 不可分享链接,刷新页面会丢失 |
动态路由参数 | 结构清晰,语义化强 | 配置复杂,不够灵活 |
实战案例
电商商品详情页跳转
// 商品列表页
function ProductList() {
const navigate = useNavigate();
const handleClick = (product) => {
navigate(`/product/${product.id}`, {
state: {
from: 'list',
timestamp: Date.now()
}
});
};
return (
<div>
{products.map(p => (
<button
key={p.id}
onClick={() => handleClick(p)}
>
{p.name}
</button>
))}
</div>
);
}
// 商品详情页
function ProductDetail() {
const { id } = useParams();
const { state } = useLocation();
const [product, setProduct] = useState(null);
useEffect(() => {
fetchProduct(id).then(data => setProduct(data));
console.log('来自:', state?.from); // 'list'
}, [id]);
return (
<div>
<h1>{product?.name}</h1>
{/* 商品详情渲染 */}
</div>
);
}
复杂搜索页面
// 搜索表单组件
function SearchForm() {
const [searchParams, setSearchParams] = useSearchParams();
const [filters, setFilters] = useState({
keyword: '',
category: 'all',
sort: 'newest'
});
const handleSubmit = (e) => {
e.preventDefault();
setSearchParams({
q: filters.keyword,
cat: filters.category,
sort: filters.sort
});
};
return (
<form onSubmit={handleSubmit}>
{/* 表单控件 */}
</form>
);
}
// 搜索结果页
function SearchResults() {
const [searchParams] = useSearchParams();
const [results, setResults] = useState([]);
useEffect(() => {
const keyword = searchParams.get('q');
const category = searchParams.get('cat');
const sort = searchParams.get('sort');
searchProducts({ keyword, category, sort })
.then(data => setResults(data));
}, [searchParams]);
return (
<div>
{/* 搜索结果渲染 */}
</div>
);
}
小结
React路由传参方式多样,各有适用场景:
1. 简单标识优先使用URL参数(/user/:id
)
2. 可选参数使用查询参数(?page=1&sort=asc
)
3. 复杂对象使用状态参数(navigate(path, { state })
)
4. 结构化路径使用动态路由(/blog/2023/05/15
)
在React-Router v6中,推荐使用新的Hooks API(useNavigate
、useParams
、useSearchParams
等)来简化路由操作。同时注意,状态参数虽然方便,但不适合需要持久化的数据,对于关键数据应考虑存储在URL或状态管理库中。
选择传参方式时,始终考虑用户体验(URL可分享性)和开发体验(代码可维护性)的平衡,才能构建出既好用又健壮的React应用。