“这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战”
前言
React作为一个MVVM框架,路由功能是必不可少的,回顾我们在使用Vue Router的过程中,最常用的一些功能是路由页面的渲染,路由页面内容的添加,路由地址的配置,路由跳转,路由传参、嵌套路由等等,本文将去React Router中寻找这些常用功能的是如何实现的,来带你入门 React Router5.0。
在上篇文章中介绍了路由页面如何渲染 、路由页面内容如何设置、如何设置路由地址,本文将继续介绍路由如何跳转、如何接收路由的传参、路由懒加载。
一、路由如何跳转
在Vue Router中有两种方式进行路由跳转,一种是声明式,一种是编程式。
声明式 | 编程式 | <router-link :to="..."> | router.push(...) |
---|
那React Router中是否也有声明式和编程式的路由跳转?举一个例子来介绍,例如:实现一个点击第一个页面跳转到第二个页面,点击第二个页面跳转到第一个页面。
1.1 声明式路由跳转
使用 Link 组件来实现跳转,其属性to
可设置要跳转的路由地址,切记 Link 组件必须在 Route 组件内使用。
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route ,Link} from "react-router-dom";
ReactDOM.render(
<div>
<BrowserRouter>
<Route
path="/one"
render={() => {
return (
<div><Link to="/two">去第二个页面</Link></div>
)
}}
>
</Route>
<Route
path="/two"
render={() => {
return (
<div><Link to="/one">去第一个页面</Link></div>
)
}}
></Route>
</BrowserRouter>
</div>,
document.getElementById('root')
);
1.2 编程式路由跳转
在类组件和函数组件中的用法是不同的,分别来介绍。
1.2.1 函数组件中的编程式路由跳转
执行useHistory()
Hook 来获取history
,然后调用history.push(path)
进行路由跳转。
1.2.2 类组件中的编程式路由跳转
在类组件中通过props
获取到history
,然后调用history.push(path)
进行路由跳转。
具体实现看下面demo。
import React from 'react';
import ReactDOM from 'react-dom';
import {
BrowserRouter,
Route,
useHistory
} from "react-router-dom";
class OnePage extends React.Component {
constructor(props) {
super(props)
const { history } = this.props;
this.history = history;
this.jump = this.jump.bind(this)
}
jump = () => {
this.history.push('/two')
}
render() {
return (
<div>
<div onClick={this.jump}>去第二个页面</div>
</div>
)
}
}
const TwoPage = () => {
const history = useHistory();
const handleClick = () => {
history.push("/one");
}
return (
<div onClick={handleClick}>去第一个页面</div>
)
}
ReactDOM.render(
<div>
<BrowserRouter>
<Route
path="/one"
component={OnePage}
>
</Route>
<Route
path="/two"
component={TwoPage}
></Route>
</BrowserRouter>
</div>,
document.getElementById('root')
);
二、如何接收路由的传参
在类组件和函数组件中的接收路由参数的做法是不同的,要分别来介绍。另外每一种接收路由的传参都对应着一种传递路由参数的方法,且在类组件和函数组件中是一致的,会穿插在每种接收路由的传参的方法中介绍。
2.1 在函数组件中接收路由传参
在函数组件中有三个Hook(useLocation
、useParams
、useRouteMatch
)可以接收路由参数,下面来详细介绍各自的使用方法。
2.1.1 useLocation
const location = useLocation();
console.log(location)
先在函数组件中执行useLocation,并将结果打印出来,看一下结果,如下图所示:
主要关注结果中的search
和state
这个两个属性,这两个属性是用来接收路由的传参。
那要怎么传参,才能用useLocation返回的对象中的search
和state
接收到路由的传参。在上一小节可知路由的跳转有两种,一种是声明式,一种是编程式。
search
接收跳转地址的请求参数,如:/one?id=1
时,search
为?id=1
,可以在声明式跳转中这样传参。
state
接收history.push
中的第二参数作为传参,如:history.push('/one',{name:'第一个页面'})
,一般在编程式跳转中这样传参。
import React from 'react';
import ReactDOM from 'react-dom';
import {
BrowserRouter,
Route,
Link,
useLocation,
useHistory
} from "react-router-dom";
const OnePage = () =>{
const location = useLocation();
console.log('第一个页面',location)
return (
<div><Link to="/two?id=2">去第二个页面</Link></div>
)
}
const TwoPage= () =>{
const location = useLocation();
console.log('第二个页面',location)
const history = useHistory();
const toOnePage = () =>{
history.push('/one',{name:'第一个页面'})
}
return (
<div onClick={toOnePage}>去第一个页面</div>
)
}
ReactDOM.render(
<div>
<BrowserRouter>
<Route
path="/one"
component={OnePage}
>
</Route>
<Route
path="/two"
component={TwoPage}
></Route>
</BrowserRouter>
</div>,
document.getElementById('root')
);
将 OnePage 和 TwoPage 两个组件中的执行useLocation()
的结果都打印出来,如下图所示:
当使用history.push('/one',{name:'第一个页面'})
跳转到第一个页面时,useLocation()
的结果中的state
的值为{name: "第一个页面"}
。
当使用<Link to="/two?id=2">去第二个页面</Link>
跳转到第二个页面时,useLocation()
的结果中的search
的值为"?id=2"
。
2.1.2 useParams
useParams
接收跳转地址的路径参数,如/one/1
,其中1
就是路径参数。
要先用特定的写法给 Route 组件的path
属性添加路径,才能用useParams
接收到路径参数。
例如path
设置为/one/:id/:num
,若路由跳转地址为/one/2/3/4
,那么用useParams
接收的值为{id:2,num:3}
。
下面用一个例子具体演示一下,还是点击第一个页面跳转第二页面,点击第二个页面跳转第一页面,注意观察各自 Route 组件的path
属性值、路由跳转地址和各自组件内执行useParams()
的结果。
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter,
Route,
Link,
useHistory,
useParams
} from "react-router-dom";
const OnePage = () =>{
const params = useParams();
console.log('第一个页面',params);
return (
<div><Link to="/two/2/3">去第二个页面</Link></div>
)
}
const TwoPage= () =>{
const params = useParams();
console.log('第二个页面',params);
const history = useHistory();
const toOnePage = () =>{
history.push('/one/1/3')
}
return (
<div onClick={toOnePage}>去第一个页面</div>
)
}
ReactDOM.render(
<div>
<BrowserRouter>
<Route
path="/one/:id/:num"
component={OnePage}
>
</Route>
<Route
path="/two/:id"
component={TwoPage}
></Route>
</BrowserRouter>
</div>,
document.getElementById('root')
);
将上面demo中各自组件内执行useParams()
的结果打印出来,如下图所示:
此外要特别注意,若给一个 Route 组件设置的path
带路径参数的变量,设置几个,访问这个 Route 组件的URL也要有几个路径参数,否是访问不了。
2.1.3 useRouteMatch
执行useRouteMatch()
可得到当前路由页面的路由数据。数据中有个params
的字段,其值和执行useParams()
得到数据一样。
所以使用useRouteMatch
获取路由参数,也要先用特定的写法给 Route 组件的path
属性添加路径,才能用useRouteMatch
接收到路径参数。
例如将渲染“第一页面”的 Route 组件的path
设置为/one/:id/:num
,若路由跳转地址为/one/2/3/4
,那么在“第一页面”路由页面组件中执行useRouteMatch()
,
import {
useRouteMatch
} from "react-router-dom";
const OnePage = () =>{
const match = useRouteMatch();
console.log(match);
return (
<div>第一个页面</div>
)
}
可得到当前路由页面的路由数据match
如下所示:
其中红框部分就是路由参数,是不是和执行useParams()
得到数据一样?
2.2 在类组件中接收路由传参
在类组件中通过props
获取到location
和match
,然后在其中获取到路由参数search
(请求参数)、params
(路径参数)和state
。
在“第一页面”这个路由页面组件中把props
打印出来。
class OnePage extends React.Component {
constructor(props) {
super(props)
console.log(this.props)
}
render() {
return (
<div>
<div>第一个页面</div>
</div>
)
}
}
打印结果如下图所示:
至于路由参数search
(请求参数)、params
(路径参数)和state
如何传递已经在上小节【在函数组件中接收路由传参】中介绍过了。
三、路由懒加载
使用React.lazy
定义一个动态加载的组件,来实现路由懒加载。
例如把OnePage这个路由页面组件进行懒加载,实现代码如下所示:
import React from 'react';
import ReactDOM from 'react-dom';
import {
BrowserRouter,
Route,
} from "react-router-dom";
const OnePage = React.lazy(() => import('./OnePage'));
const Spinner = () => {
return (
<div>加载中……</div>
)
}
ReactDOM.render(
<div>
<React.Suspense fallback={<Spinner/>}>
<BrowserRouter>
<Route
path="/"
component={OnePage}
>
</Route>
</BrowserRouter>
</React.Suspense>
</div>,
document.getElementById('root')
);
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!