React Router基本用法
真实项目中,一般需要通过不同的URL标识不同的页面,也就是存在不同页面间路由的需求。
单页面应用和前端路由
在传统Web应用中,浏览器会根据地址栏的URL向服务器发送一个Http请求,服务器会根据URL返回一个HTML页面。这种情况下,一个URL对应一个HTML页面,一个Web应用包含很多HTML页面,这样的应用就是多页面应用;在多页面应用中,页面路由的控制由服务端负责,这中路由方式称为后端路由。
在多页面应用中,每次页面切换都需要向服务器发送一次请求,页面使用的静态资源也需要重新请求加载,存在一定浪费。而且,页面的整体刷新对用户体验也有影响,因为不同页面间往往存在共同的部分,页面整体刷新也会导致共用部分刷新。
单页面应用虽然名为“单页面”,但视觉上的感受仍为多页面,因为URL发生了变化,页面的内容也发生了变化,但是这只是逻辑上的多页面,实际上无论URL如何变化,对应的HTML文件都是同一个。
单页面应用中,URL发生变化并不会向服务器发送新的请求,所以”逻辑页面“的路由只能由前端负责,这种路由称为前端路由。
通过ReactRouter可以让Web应用根据不同的URL渲染不同的组件,这样的组件渲染方式可以解决更复杂的业务场景。
React Router的安装
ReactRouter包含三个库:
-
react-router
提供最基础的功能;
-
react-router-native
react-router的native版本;
-
react-router-dom
react-router的浏览器版本;
路由器
React Router通过Router和Route两个组件完成路由功能。
Router可以理解为路由器,一个应用中只需要一个Router实例,所有的路由器配置组件Route都定义为Router的子组件。
在Web应用中,一般会使用对Router进行包装的BrowserRouter或者HashRouter两个组件。
BrowserRouter使用HTML5的history API实现应用的UI和URL同步。
BrowserRouter创建的URL形式如下:
http://xxxxx.com/xxxx/xxx
HashRouter使用URL的hash实现应用的UI和URL同步。
HashRouter创建的URL形式如下:
http://xxxxx.com/#/xxxx/xxx
使用BrowserRouter时,一般还需要对服务器进行配置,让服务器能够正确地处理所有可能的URL。
使用HashRouter时,不需要配置服务器,因为Hash部分的内容会被服务器自动忽略,真正有效的信息是Hash前面的部分,对于单页面应用来说,这部分是固定的。
Router会创建一个history对象,history用来跟踪URL,当URL发生变化时,Router的后代组件会重新渲染。
ReactRouter中提供的其他组件可以通过context获取history对象。
路由配置
Route时ReactRouter中用于配置路由信息的组件,也是ReactRouter中使用频率最高的组件。
每当有组件需要根据URL决定是否渲染时,就需要创建一个Route。
path
每个Route都需要定义一个path属性。
当使用BrowserRouter时,path用来描述这个Route匹配的URL的pathname;
当使用HashRouter时,path用来描述这个Route匹配的URL的hash;
当URL匹配一个Route时,这个Route定义的组件就会被渲染出来,反之不会被渲染。
match
当URL和Route匹配时,Route会创建一个match对象作为props中的属性传递给被渲染的组件。
这个对象还包含如下属性:
-
params
Route的path可以包含参数,params用于匹配从URL中解析出来的path中的参数。
例如:
<Route path='/xxx/:id'> URL="http://xxxx.com/xxx/1"
此时:
params={ id: 1 }
-
isExact
为布尔值,当URL完全匹配时,取值为true;
部分匹配时,取值为false;
-
path
Route的path属性,多用于构建嵌套路由;
-
url
URL的匹配部分;
Route渲染组件的方式
Route提供了三个属性,用于定义待渲染的组件:
-
component
component的值是一个组件,当URL和Route匹配时,component属性定义的组件就会被渲染。
-
render
render的值是一个函数,这个函数返回一个React元素。
这种方式可以方便地为带渲染组件传递额外的属性。
-
children
children的值也是一个函数,函数返回要渲染的React元素。
与前两种方法不同的地方是,无论是否匹配成功,children返回的组件都会被渲染。
但是,如果匹配不成功时,match属性取值为null。
Switch和exact
当URL和多个Route匹配时,这些Route都会被执行渲染操作。
如果只想让第一个匹配的Route渲染,那么可以把这些Route作为一个Switch组件的子组件。
如果想让URL和Route完全匹配时,Route才渲染,那么可以使用Route的exact属性。
链接
Link使用to属性来声明要导航到的URL地址。
to可以是String或者object类型,当to为object类型时,可以包含pathname、search、hash和state四个属性。
后台服务API
在package.json中配置代理信息:
"proxy": "http://localhost:8080"
路由设计
路由设计的过程可分为以下两步:
- 为每一个页面定义有语义的路由名称(path);
- 组织Route结构层次;
示例代码:
import { Router, Route, Switch } from 'react-router';
import { Home } from '../component/Home';
import { Login } from '../component/Login';
function AppRouter() {
return(
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="posts" component={Home} />
</Switch>
</Router>
);
}
export default AppRouter;