一、React路由传参的三种方式
React Router提供了3种方式来传递参数:params、query、state。下面我们将介绍每种方式的使用方法和优缺点。
1. Params传参
Params是一种通过URL片段来传递数据的方式。在Route组件中可以通过路径参数定义,例如:
{
/*在App.js定义路由*/
<Route path="/article/:id" component={Article} />
}
在Link组件中可以通过to属性来传递参数:
{
<Link to=`/article/${article.id}`>查看详情</Link>
}
在被链接组件中可以通过props.match.params获取参数:
{
class Article extends React.Component {
render() {
const { match } = this.props;
const id = match.params.id; //获取参数
return <div>Article ID: {id}</div>;
}
}
}
优点:可以定义动态路由,传递的参数可以直接在props中获取。
缺点:对于大型应用程序,可能需要多个地方获取该参数,因此不太方便。
2. Query传参
Query是一种通过URL参数来传递数据的方式。在Link组件中可以通过to属性传递参数:
{
<Link to={{pathname: '/article', search: '?id=' + article.id}}>查看详情</Link>
}
在被链接组件中可以通过props.location.search获取参数:
{
class Article extends React.Component {
render() {
const { location } = this.props;
const searchParams = new URLSearchParams(location.search); //获取参数
const id = searchParams.get('id');
return <div>Article ID: {id}</div>;
}
}
}
优点:将参数集中在URL上,方便管理。
缺点:URL太长,不太美观;参数只能是字符串,如果需要传递对象需要进行序列化和反序列化。
3. State传参
State通过Link组件中的state属性传递参数。例如:
{
<Link to={{
pathname: '/article',
state: { id: article.id }
}}>查看详情</Link>
}
在被链接组件中可以通过props.location.state获取参数:
{
class Article extends React.Component {
render() {
const { location } = this.props;
const id = location.state.id; //获取参数
return <div>Article ID: {id}</div>;
}
}
}
优点:参数不会被暴露在URL中,安全性较高。
缺点:如果用户使用了浏览器的前进或后退按钮,参数会丢失。因此不太适合需要永久保存参数状态的情况。
二、React路由传参数
使用React Router中的参数传递,可以方便地将参数传递给组件,在组件中进行处理。下面是一个例子。
{
/*在App.js定义路由*/
<Route path="/article/:id" component={Article} />
/*在Link组件中传递参数*/
<Link to=`/article/${article.id}`>查看详情</Link>
/*在被链接组件中获取参数*/
class Article extends React.Component {
render() {
const { match } = this.props;
const id = match.params.id;
//渲染页面
return (
<div>
<h1>{this.props.title}</h1>
<p>{this.props.content}</p>
</div>
);
}
}
}
上面的例子中,参数id被传递到了Article组件中,在组件中可以根据传递的参数进行页面渲染。
三、React路由传参丢失
在使用React路由传参时,有时会出现参数丢失的情况。下面我们来分析一下可能的原因和解决方法。
1. 刷新页面导致参数丢失
在使用params方式传递参数时,参数是作为URL的一部分存在的。如果用户在刷新页面时,URL会改变,从而导致参数丢失。
解决方法:使用localStorage或sessionStorage将参数保存在本地,这样用户刷新页面时可以从本地存储中重新获取参数。
2. 浏览器前进或后退按钮导致参数丢失
在使用state方式传递参数时,如果用户使用了浏览器的前进或后退按钮,参数会丢失。
解决方法:将参数保存在URL中或使用localStorage或sessionStorage。
3. 组件传递给子组件时参数丢失
在父组件中使用Route组件传递参数给子组件时,如果不使用render函数,则无法传递参数。
解决方法:使用render函数进行组件渲染,并将参数传递给组件。
四、React路由组件
React Router提供了一些内置的组件,可以方便地构建应用程序的路由。下面是一些常用的路由组件。
1. Route组件
Route组件是React Router中最基本的组件,可以用来定义路由和渲染组件。下面是一个例子。
{
<Route path="/article/:id" component={Article} />
//...
class Article extends React.Component {
render() {
//渲染页面
return (
<div>
<h1>{this.props.title}</h1>
<p>{this.props.content}</p>
</div>
);
}
}
}
上面的例子中,Route组件定义了路径为"/article/:id"的路由,并将Article组件与该路由对应。当用户访问该路由时,React Router会自动渲染Article组件,并将URL参数传递给该组件。
2. Switch组件
Switch组件用于对路由进行分组,只渲染第一个匹配的路由。例如:
{
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />
<Route path="/article/:id" component={Article} />
<Route component={NotFound} />
</Switch>
}
上面的例子中,Switch组件将"/"、"/about"、"/article/:id"和默认路由包括在一起,并且只有第一个匹配的路由会被渲染,可以有效防止默认路由重复渲染的问题。
3. withRouter组件
withRouter组件是React Router提供的一个高阶组件(HOC),用于将路由对象注入到组件中。使用withRouter将允许你在不是路由组件的任何地方使用路由对象。
{
import { withRouter } from 'react-router-dom';
class MyComponent extends React.Component {
handleClick() {
this.props.history.push('/about');
}
render() {
return (
<div onClick={() => this.handleClick()}>
Go to About
</div>
);
}
}
export default withRouter(MyComponent);
}
上面的例子中,使用withRouter将路由对象注入到MyComponent中,在组件中就可以使用history.push方法进行路由跳转。
五、React路由重定向
React Router提供了Redirect组件,用于实现路由重定向。例如,当用户未登录时,可以将其重定向到登录页面。
{
import { Redirect } from 'react-router-dom';
class MyComponent extends React.Component {
render() {
const isLoggedIn = false;
return isLoggedIn ? (
<div>You are logged in.</div>
) : (
<Redirect to="/login" />
);
}
}
}
上面的例子中,如果用户未登录,则React Router将其重定向到"/login"页面。
六、React路由面试题
下面是一些React路由面试题,可以帮助你加深对React路由的理解。
1. 路由是否可以传递函数作为参数?
答案:不能。因为React Router路由组件只能接受React组件作为参数。
2. 如何在React Router中实现动态路由?
答案:使用params方式传递参数。在Route组件的path属性中使用冒号(:)定义参数,例如"/article/:id"。在Link组件中使用to属性传递参数,例如:<Link to=`/article/${article.id}`>查看详情</Link>。在被链接组件中可以通过props.match.params获取参数。
3. 如何实现路由跳转?
答案:使用history对象中的push或replace方法进行路由跳转。例如:this.props.history.push('/about')。
七、React路由参数配置
React Router使用
{
import { Route } from 'react-router-dom';
class MyComponent extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
</div>
);
}
}
<Route path="/hello" component={MyComponent} />
}
上面的例子中,当用户访问"/hello"页面时,MyComponent组件将会被渲染。
八、React路由式导航如何传值
使用React Router可以方便地实现式导航。例如,将导航栏作为组件,在点击时根据路由进行页面跳转。下面是一个例子。
{
import { NavLink } from 'react-router-dom';
class Nav extends React.Component {
render() {
return (
<div>
<ul>
<li><NavLink to="/home" activeClassName="active">Home</NavLink></li>
<li><NavLink to="/about" activeClassName="active">About</NavLink></li>
<li><NavLink to="/contact" activeClassName="active">Contact</NavLink></li>
</ul>
</div>
);
}
}
}
上面的例子中,使用NavLink组件实现导航栏。当用户点击链接时,React Router根据路由进行页面跳转,并使用activeClassName属性添加样式。
总结
React路由传参