markdown 反应路由器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 反应路由器相关的知识,希望对你有一定的参考价值。
## 概述
react-router是用于实现React项目中路由功能的库,对于构建SPA React项目非常有必要,react-router4.x对react-router整体进行了重写,API也相对于3.x有了很大的改变,可以理解4.x和3.x是两个完全不同的工具,3.x主张集中配置route,4.x则将每一个路由都当做普通React component,因此route的配置会融入到整个项目的代码中,它的作者把这个称之为动态路由。这里重点介绍react-router4.x的使用。
## 安装
react-router将之前的库拆分成以下三个库:
* react-router:react-router的核心代码;
* react-router-dom:Dom绑定的react-router,依赖react-router;
* reat-router-native:react native绑定的react-router,依赖react-router;
对于react项目,我们只需要安装 react-router-dom即可:
```sh
npm install react-router-dom --save
```
## Router
react-router提供好几种router来满足不同的需求:
* BrowserRouter:使用传统网站方式的路由,用path来指定不同路由,对于这种Router,需要在服务端进行设置将所有路由范围内的请求指向到一个静态Html;
* HashRouter:使用hash值来指定不同路由,对于使用static形式来作为服务端的情况,用这种router非常方便,不需要服务端做任何额外的配置;
* MemeryRouter:将路由指定存放在内存中,通常用于测试环境、没有浏览器的环境或者是react native;
* StaticRouter:用于不需要改变location的router;
其中使用最多的是BrowserRouter和HashRouter,这里用HashRouter举例:
```js
import {HashRouter} from 'react-router-dom';
ReactDOM.render((
<HashRouter>
<App />
</HashRouter>
), document.getElementById('root'))
```
## Route
Route组件是react-router中最重要也是最常用的组件,它通常的作用是当url和组件的path属性匹配时渲染相应的UI组件。
Route可以通过3种方式来指定UI:
* ```<Route component>```
```js
import {Route} from 'react-router-dom';
import Page1 from './page1';
export default (props) => {
return (
<div>
<Route path="/page1" component={Page1} />
</div>
);
}
```
> 这种方式其实是route通过React.createElement来创建一个component指定组件的实例,需要注意的是如果component组件传入一个inline函数来返回一个组件,那么每次render就会创建一个新的实例,这样就导致已有的组件实例没有销毁,新的实例又创建了,而不是直接更新已有的实例,因此对于这种情况,建议使用下面两种方式。
* ```<Route render>```
```js
import {Route} from 'react-router-dom';
export default (props) => {
return (
<div>
<Route path="/page2" render={(props) => (
<div>
page2 yoyoyo
</div>
)} />
</div>
);
}
```
* ```<Route children>```
通过children属性来指定UI组件,接受一个参数为match的函数,使用者可以根据是否匹配path来选择渲染不同的UI组件。
```js
import {Route} from 'react-router-dom';
export default (props) => {
return (
<div>
<Route path="/page2" children={({match}) => {
if (match) {
return (<div> match the path</div>);
} else {
return (<div> not match the path</div>);
}
}} />
</div>
);
}
```
Route组件可以配置如下参数来指定url匹配规则:
* path:string类型,[path-to-regexp](https://www.npmjs.com/package/path-to-regexp)形式,用于指定需要匹配的path,若不指定,表明匹配所有的path;
* exact:bool类型,用于指定完全匹配path,如下所示:
|path|location.pathname|exact|match?|
|-|-|-|-|
|/one|/one/two|false|yes|
|/one|/one/two|true|no|
* strict: bool类型,若设置为true且path末尾跟一个‘/’,那么只能匹配后面跟有‘/’的pathname,若设置为true,如下所示:
|path|location.pathname|match?|
|-|-|-|-|
|/one/|/one|no|
|/one/|/one/|yes|
|/one/|/one/two|yes|
* location: object类型,默认情况下Route会匹配当前浏览器中的location,通过location我们可以自定义一个location来用于匹配;
Route在指定渲染UI组件时会给组件注入3个props:
* match:是一个用描述match情况的对象,主要包含以下内容:
* params:key/value对,用于记录path中变量的值,例如/page/:id中的id;
* isExtract:bool类型,表示是否绝对匹配;
* path:string类型,进行匹配的path,通常用于嵌套route的时候;
* url:string类型,匹配的URL部分,通常用于嵌套link的时候;
* location:用于记录当前location相关描述,通常是下面这个样子:
```js
{
key: 'ac3df4', // not with HashHistory!
pathname: '/somewhere'
search: '?some=search-string',
hash: '#howdy',
state: {
[userDefined]: true
}
}
```
> 在history的属性中也有一个history.location,但是通常建议使用这个,因为history下面的location会发生突变,这个不会。
* history:history用于记录history相关的描述,主要包含以下属性:
* length:history栈中的实体数量;
* action:指明当前的action(PUSH、POP或REPLACE);
* location:同上面介绍的location;
* push:push一个新的实体到history栈中;
* replace:替换history栈中的当前实体;
* go:移动history栈中当前实体的指针;
* goBack:相当于go(-1);
* goForward: 相当于go(1);
* block: 阻止导航;
## Redirect
用于将当前locaction重定向到一个新的location,新的location将替换掉history栈中的当前实体。通常用法:
```js
//接受string
<Redirect push to="/somewhere/else"/>
//接受object
<Redirect to={{
pathname: '/login',
search: '?utm=your+face',
state: { referrer: currentLocation }
}}/>
//在switch中使用
<Switch>
<Redirect from='/old-path' to='/new-path'/>
<Route path='/new-path' component={Place}/>
</Switch>
```
## Switch
Switch用来包裹Route和Redirect,并render第一个匹配的Route或Redirect。因此它是有排他性的,不使用switch的情况下,会渲染所有匹配的Route或Redirect。
如下所示,如果访问/about,三个组件都会被渲染:
```js
<Route path="/about" component={About}/>
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>
```
如果按照下面的方式来写,往往更能达到用户的期望:
```js
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>
</Switch>
```
> Switch中只能使用Route和Redirect子元素
> Switch可以设置一个location熟悉来替代当前浏览器location
> 没有path的Route和没有from的Redirect都可以匹配所有链接
## Link & NavLink
Link类似a标签,用于进行页面跳转,默认是使用push的方式,通常用法如下所示:
```js
<Link to="/courses"/>
<Link to={{
pathname: '/courses',
search: '?sort=name',
hash: '#the-hash',
state: { fromDashboard: true }
}}/>
<Link to="/courses" replace />
```
NavLink是一种特殊的Link,它可以将样式属性传递给当前组件,如果to设置的path匹配当前URL,最常见的场景就是导航条。基本用法如下:
```js
//设置class
<NavLink
to="/faq"
activeClassName="selected"
>FAQs</NavLink>
//设置属性
<NavLink
to="/faq"
activeStyle={{
fontWeight: 'bold',
color: 'red'
}}
>FAQs</NavLink>
//支持exact和strict属性
<NavLink
exact
strict
to="/profile/"
>Profile</NavLink>
```
我们也可以设置一个isActive属性来处理一些特殊逻辑:
```js
const oddEvent = (match, location) => {
if (!match) {
return false
}
const eventID = parseInt(match.params.eventID)
return !isNaN(eventID) && eventID % 2 === 1
}
<NavLink
to="/events/123"
isActive={oddEvent}
>Event 123</NavLink>
```
## 参考
* https://reacttraining.com/react-router/web/example/basic
* https://medium.com/@pshrmn/a-simple-react-router-v4-tutorial-7f23ff27adf
以上是关于markdown 反应路由器的主要内容,如果未能解决你的问题,请参考以下文章