React Router 进修手册(基本篇)

该手册是基于react-routerReact Router 运用教程 进修编写而成,可以会有形貌不够清晰的处所,人人可自行参考原文,

React RouterReact 供应了一个完全的路由库,它许可你经由过程 URl 的变化来掌握组件的切换与变化

有关 React 百口桶的其他相干文章,可以检察以下链接,会延续更新

装置

运用 npm 举行装置:

npm install --save react-router

以后在须要用到的处所举行援用,

// 须要用到 ES6 编译器,比方 babel
import { Router, Route, Link } from 'react-router'

// 不须要运用编译器
var Router = require('react-router').Router
var Route = require('react-router').Route
var Link = require('react-router').Link

固然也可以运用 script 标签举行援用:

<script src="https://unpkg.com/react-router/umd/ReactRouter.min.js"></script>

以后可以经由过程 window.ReactRouter 举行挪用

概述

样例概述

当我们想要完成相似信息系统的界面,进入到收件箱挑选检察详细信息 1234 的时刻,界面路由以下:

path: /inbox/messages/1234

+---------+------------+------------------------+
| About   |    Inbox   |                        |
+---------+            +------------------------+
| Compose    Reply    Reply All    Archive      |
+-----------------------------------------------+
|Movie tomorrow|                                |
+--------------+   Subject: TPS Report          |
|TPS Report        From:    boss@big.co         |
+--------------+                                |
|New Pull Reque|   So ...                       |
+--------------+                                |
|...           |                                |
+--------------+--------------------------------+

应当完成以下几种路由:

URLComponents
/App -> Home
/aboutApp -> About
/inboxApp -> Indox
/inbox/messages/:idApp -> Inbox -> Message

运用 react-router 举行完成


// 省略部份组件定义
const App = React.createClass({
  render() {
    return (
      <div>
        <h1>App</h1>
        {/* 运用 `<Link>` 标签举行路由跳转 */}
        <ul>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/inbox">Inbox</Link></li>
        </ul>
        {this.props.children}
      </div>
    )
  }
})

const About = ...;
const Home = ...;

const Inbox = (props) => {
  return (
    <div>
       <h2>Inbox</h2>
       {props.children}
     </div>
  )
}
const IndexStatus = ...;
const Message = ...;

// <Router> 是一个 React 组件
// <Router> 同时也是 <Route> 的一个容器,路由划定规矩运用 <Route> 举行定义
render((
  <Router history={hasHistory}>
    <Route path="/" component={App}>
      {/*
        当我们接见 `/` 的时刻不会有加载任何子组件,组件 `<App>` 的 `this.props.children`为 `undefined`,
        所以我们运用 `<IndexRoute>`  来指定默许加载的子组件
      */}
      <IndexRoute compoent={Home} />
      <Route path="about" component={About} />
      <Route path="inbox" component={Inbox}>
        <IndexRoute component={IndexStatus} />
        { /* 婚配 `/index/messages/123` 路由*/ }
        <Route path="messages/:id" component={Message} />
        { /* 固然我们可以直接婚配 `messages/123`,但不损坏路由组件构造 */}
        <Route component={Inbox}>
          <Route path="messages/:id" component={Message} />
        </Route>
      </Route>
    </Route>
  </Router>
), document.body)

Route 详解

一个路由由三个属性来决议它是否能婚配上 URL:

  • 嵌套构造

  • Path 属性

  • 优先级

嵌套

当一个 URL 被挪用,React Router 许可你经由过程嵌套路由 (Nested routes) 的体式格局来声明将要被衬着的一系列嵌套组件,嵌套路由是类树状构造 (tree-like structure),React Router 经由过程 route config 的递次去婚配 URL

RouteConfig 是 React Router 内部用来指定 router 递次的数组

<Router history={hashHistory}>
  <Route path="/" component={App}>
    <Route path="/repos" component={Repos}/>
    <Route path="/about" component={About}/>
  </Route>
</Router>

Path 语法

  • :paramName,婚配 URL 的一个部份,直到碰到下一个/、?、#

  • (),示意URL的这个部份是可选的

  • *,婚配恣意字符(非贪欲情势),直到情势内里的下一个字符为

  • **,婚配恣意字符(贪欲情势),直到下一个/、?、#为止

贪欲情势:在全部表达式婚配胜利的前提下,只管少的婚配
非贪欲情势:在全部表达式婚配胜利的前提下,只管多的婚配

<Route path="/hello/:name">         // 婚配 /hello/michael 和 /hello/ryan
<Route path="/hello(/:name)">       // 婚配 /hello, /hello/michael, 和 /hello/ryan
<Route path="/files/*.*">           // 婚配 /files/hello.jpg 和 /files/hello.html
<Route path="/**/*.jpg">            // 婚配 /files/hello.jpg 和 /files/path/to/file.jpg

优先级

React Router 是经由过程从上到下的递次婚配路由的,所以应当只管保证同级路由的第一个路由不会婚配上一切可以的 Path,比方:

<Route path="/comments" ... />  
<Redirect from="/comments" ... /> // 这一条路由划定规矩是不会实行的,认为上一条路由已婚配了一切途径为 `/comments`

Histories

React Router 构建于 history,简而言之,React Router history 属性用于监听浏览器地点栏的变化,
并将 URL 剖析后放入进 location 对象中,给 React Router 供应婚配,

我们运用以下体式格局从 React Router Package 中援用,

import { browserHistory } from 'react-router'

然后在 <Router> 中运用,

render(
  <Router history={browserHistory} routes={routes} />,
  document.getElementById('app')
)

有三种 history 属性范例:

browserHistory

Browser history 是经由过程 URL 变化来转变路由的,它是背地挪用的是浏览器的 History

然则,运用 Browser history 是须要设置你的服务器

hashHistory

Hash history 运用哈希符 (#) 作为 URL 的一部份,路由经由过程哈希符的部份举行切换,URL 的情势相似于,example.com/#/some/path

我该运用 hashHistory 么?

Hash history 不须要你设置服务器即可运用,当你方才最先运用 React Router 的时刻,就是用它吧,然则一般来说,临盆环境下的 web 运用应当运用 browserHistory 来坚持 URLs 的整齐度,而且 hashHistory 是不支撑服务端衬着的

实际运用当中,我们会发明详细的 URL 可以为 example.com/#/some/path?_k=ckuvup

所以 ?_k=ckuvup 是渣滓代码什么

当我们运用 web 运用的时刻,浏览器纪录 (history) 经由过程 push 或许 replace 来发生变更,浏览器纪录会存储一个地点状况 (location state),但并不会体现在 URL 中,

相干的 API 可以参考 History

而在 DOM API 中,转变 Hash history 的体式格局仅仅是经由过程 window.location.hash = newHash,这并没有方法保留地点状况,然则我们愿望一切的历史纪录都可以运用地点状况,所以我们为每个地点发生一个举世无双的键值用以示意地点状况,当我们在浏览器中点击退却或许行进的时刻,我们就有方法来之前的地点状况了

createMemoryHistory

Memory history 并不会从地点栏中操纵或是读取,它可以协助我们完成服务器端的衬着,或许用于测试以及其他衬着环境 (比方 React Native),和其他两种体式格局不一样的是,我们须要在内存中建立 history 对象来运用,

const history = createMemoryHistory(loaction)

Index Routes and Index Links

Index Routes

斟酌以下代码,

<Router>
  <Route path="/" component={App}>
    <Route path="accounts" component={Accounts}/>
    <Route path="statements" component={Statements}/>
  </Route>
</Router>

当我们接见 / 的时刻不会有加载任何子组件,组件 <App>this.props.childrenundefined

固然你可以运用 {this.props.children || <Home />} 来定义衬着默许组件,

Home 并没有出现在路由当中,所以如许写并非异常直观,因而可以运用 <IndexRoute> 来指定当指定子组件不存在时加载默许的子组件,

<Router>
  <Route path="/" component={App}>
    <IndexRoute component={Home}/>
    <Route path="accounts" component={Accounts}/>
    <Route path="statements" component={Statements}/>
  </Route>
</Router>

Redirect and Index Redirects

我们可以运用 <Redirect> 组件来定义从一个路由自动跳转至另一个路由,

<Route path="inbox" component={Inbox}>
  {/* 从 /inbox/messages/:id 跳转到 /messages/:id */}
  <Redirect from="messages/:id" to="/messages/:id" />
</Route>

斟酌以下代码,

<Route path="/" component={App}>
  <Route path="welcome" component={Welcome} />
  <Route path="about" component={About} />
</Route>

当我们愿望接见 / 的时刻自动跳转至 welcome ,即当我们接见跟路由 / 的时刻从定向为其他组件,我们可以运用 <IndexRedirect> 组件,

<Route path="/" component={App}>
  <IndexRedirect to="/welcome" />
  <Route path="welcome" component={Welcome} />
  <Route path="about" component={About} />
</Route>

Index Links

当我们想点击一个链接跳转至根路由 / , 或许我们会这么写

<Link to="/">Home</Link>

实际上它会婚配任何故 / 最先的子路由,

当我们只愿望衬着 Home 相干的组件, 我们应当这么写

<IndexLink to="/">Home</IndexLink>

Enter and Leave Hooks

路由组件 (Route) 都具有 onEnteronLeave 钩子,当一个路由被触发时,进入该路由时触发 onEnter ,脱离该路由时触发 onLeave,这两个钩子异常的有效,比方当进入一个路由时,须要先推断时刻受权,就会可以运用 onEnter

在路由跳转过程当中,onLeave hook 会在一切将脱离的路由中触发,从最基层的子路由最先直到最外层父路由完毕,然后 onEnter hook会从最外层的父路由最先直到最基层子路由完毕,

回到概述中的例子,假如我们的路由从 /messages/5 跳转到 /about,下面是这些 hook 的实行递次:

  • /messages/:idonLeave

  • /inboxonLeave

  • /aboutonEnter

至此基本篇结束,以后我会给人人带来进阶篇,迎接人人延续关注,

同时假如文章中有任何毛病,迎接人人指出,好的文章须要你的支撑,感谢

    原文作者:awpsawps12
    原文地址: https://segmentfault.com/a/1190000007239636
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞