React-Router(V4)

  以前学习了第三版的react-router,但是第四版的改动太大了,设计理念和基本用法也不一样了,彻底能够看做另外一个路由插件来学习。react

  react-router如今分为两个部分。一个是针对浏览器运行的react-router-dom。一个是针对React Native应用的react-router-native。今天先写一篇针对web环境的笔记。要在浏览器端使用react-router V4,直接安装react-router-dom便可,他会自动下载react-router做为依赖。web

npm i react-router-dom --save

  大多数的路由插件都是在应用初始化的时候配置路由规则,react-router第四版以前也是这样:咱们先在js中定义好Router中路径和组件的关联,而后导入应用中。也就是说,对整个应用而言,路由是静态的,写死的。npm

  可是第四版,做者对插件作了大幅改动,他们称之为‘动态路由’。此时<Route>就和React的组件同样,可根据须要生成和销毁,可嵌套在其余组件中。而<Route>自己会将其path特性的路径和当前url匹配,若是匹配成功就渲染UI。因此从效用上,<Route>标签和React的视图组件彻底同样,除了多了个路由功能。api

--开始---浏览器

<Route>session

<Route>是React-Router最重要的组件。它有个path特性,若是path和当前url匹配,它会渲染视图,至于渲染什么东西,主要看<Route>中的render方法:react-router

  1.component:url匹配时渲染component指定的组件。app

<Route exact path="/" component={Home}/>

2.render:函数,url匹配时返回JSX做渲染。dom

1     <Route exact path={match.url} render={() => (
2       <h3>Please select a topic.</h3>
3     )}/>

3.chidlren:函数,无论url是否匹配,都返回JSX进行渲染。不匹配时match === null。函数

 1 <ul>
 2   <ListItemLink to="/somewhere"/>
 3   <ListItemLink to="/somewhere-else"/>
 4 </ul>
 5 
 6 const ListItemLink = ({ to, ...rest }) => (
 7   <Route path={to} children={({ match }) => (
 8     <li className={match ? 'active' : ''}>
 9       <Link to={to} {...rest}/>
10     </li>
11   )}/>
12 )

如上,ListItemLink返回一个<Route>,这个<Route>组件将被渲染成<li>。url匹配的<li>将添加active样式。

而且,这三个方法均可以传入三个route props,他们都携带和当前路由有关的信息:

match:是个对象,带有params、url、isExact、path四个属性.

  params(obj):当前url动态路径的参数。

  isExact:url是否彻底匹配:

  url(string):当前url的匹配部分。

  path(string):用于匹配的路径。

history:初学的时候能够先无论它。虽然对外暴露为一个route props。文档提到,‘history’和‘history object’都指向一个叫‘history package’的东西。它是除了React外,ReactRouter另外一个主要依赖。它提供了在不一样环境下在js层管理session history的实现。相关的history术语还有“browser history”、“hash history” 、“memory history”,这些history对象都有一只的典型的属性和方法,详见history.

location:其意义和location.href同样。表示app的当前位置,或将要去往哪(对其赋值)。它是一个对象形式,如:

1 {
2   key: 'ac3df4', // not with HashHistory!
3   pathname: '/somewhere'
4   search: '?some=search-string',
5   hash: '#howdy',
6   state: {
7     [userDefined]: true
8   }
9 }

这个对象将在上面提到的route的三个渲染方法中出现,做为其prop。在withRoute中也出现。

 

<Router>:V4中全部Router组件都基于这个底层实现

<BrowserRouter>
<HashRouter>
<MemoryRouter>
<NativeRouter>
<StaticRouter>

这几个Router是react-router应用中使用率比较高的,不过目前看最经常使用的是<BrowserRouter>和<HashRouter>。

前面提到,v4以前都采用声明式路由,但v4开始“路由即组件”,路由组件和app的组件更深刻地耦合了,看一个例子:

 1  const Nav = ()=>(
 2   <Router>
 3     <div>
 4       <ul>
 5       <li><Link to='/home' >Home</Link></li>
 6       <li><Link to='/about'>About</Link></li>
 7       <li><Link to='/else'>Else</Link></li>
 8       </ul>
 9  
10       <Route path='/home' component={Home} />
11       <Route path='/about' component={About} />
12       <Route path='/else' component={Else} />
13      </div>
14   </Router>
15 );
16 
17  export default Nav;

在v3中,因为路由规则是预先定义好的,因此只要url跳到某个路径,页面就会从新渲染(跳转)。可是v4中Link和Route必须在同一个Router下,Link点击后Router才会响应并渲染。

若是把Link放到一个Nav组件,把Route放到一个Container组件,而后将他们导入App。

App>Nav+Container

点击Nav中的Link,Container中的Route将不会渲染。这个是须要注意的。

另外,Route也能接受动态参数。

<Route path="list/:id"></Route> 
<Link to="list/12"></Link>

获取参数值:{ this.props.match.params.id }

 <Switch>

React-Router中提供的Switch组件,意义上和一部的switch语句同样,会将第一个匹配的Route渲染出来。

直接使用一组<Route>和将一组<Route>包含在<Switch>中有什么区别呢?

*纯粹是用一组Route,只要path和url匹配,Route就会渲染出来。若是有两个Route的path都匹配url,这两个Route都会被渲染。

*使用<Switch>来包裹一组Route,只有第一个匹配的Route会被渲染。

嵌套:

由上面的例子可知,Router>Link+Route的模式中,Route充当了视图(或者说页面)的角色,子级的Router>Link+Route能够嵌套在一个Route绑定的组件中,从而达到嵌套路由的目的。

不过此时子级路由的Link和Route的路径要写绝对路径。

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息