React Router 4.0 (以下简称 RR4) 已经正式发布,它遵循React的设计理念,即万物皆组件。所以 RR4 只是一堆 提供了导航功能的组件(还有若干对象和方法),具有声明式(引入即用),可组合性的特点。http://www.jianshu.com/p/e3adc9b5f75c

RR4 本次采用单代码仓库模型架构(monorepo),这意味者这个仓库里面有若干相互独立的包,分别是:

  • react-router React Router 核心
  • react-router-dom 用于 DOM 绑定的 React Router
  • react-router-native 用于 React Native 的 React Router
  • react-router-redux React Router 和 Redux 的集成
  • react-router-config 静态路由配置的小助手

本文主要讨论在 web app 中如何使用使用 RR4。

引用

react-router 还是 react-router-dom?

在 React 的使用中,我们一般要引入两个包,react 和 react-dom,那么 react-router 和react-router-dom 是不是两个都要引用呢?
非也,坑就在这里。他们两个只要引用一个就行了,不同之处就是后者比前者多出了 <Link> <BrowserRouter> 这样的 DOM 类组件。
因此我们只需引用 react-router-dom 这个包就行了。当然,如果搭配 redux ,你还需要使用 react-router-redux
what is the diff between react-router-dom & react-router?

组件

<BrowserRouter>

一个使用了 HTML5 history API 的高阶路由组件,保证你的 UI 界面和 URL 保持同步。此组件拥有以下属性:

basename: string
作用:为所有位置添加一个基准URL
使用场景:假如你需要把页面部署到服务器的二级目录,你可以使用 basename 设置到此目录。


<BrowserRouter basename="/minooo" />
<Link to="/react" /> // 最终渲染为 <a href="/minooo/react">

getUserConfirmation: func
作用:导航到此页面前执行的函数,默认使用 window.confirm
使用场景:当需要用户进入页面前执行什么操作时可用,不过一般用到的不多。


const getConfirmation = (message, callback) => {const allowTransition = window.confirm(message)callback(allowTransition)
}<BrowserRouter getUserConfirmation={getConfirmation('Are you sure?', yourCallBack)} />

forceRefresh: bool
作用:当浏览器不支持 HTML5 的 history API 时强制刷新页面。
使用场景:同上。


const supportsHistory = 'pushState' in window.history
<BrowserRouter forceRefresh={!supportsHistory} />

keyLength: number
作用:设置它里面路由的 location.key 的长度。默认是6。(key的作用:点击同一个链接时,每次该路由下的 location.key都会改变,可以通过 key 的变化来刷新页面。)
使用场景:按需设置。


<BrowserRouter keyLength={12} />

children: node
作用:渲染唯一子元素。
使用场景:作为一个 Reac t组件,天生自带 children 属性。

尝试一下


<HashRouter>

Hash history 不支持 location.key 和 location.state。另外由于该技术只是用来支持旧版浏览器,因此更推荐大家使用 BrowserRouter,此API不再作多余介绍。


<Route>

<Route> 也许是 RR4 中最重要的组件了,重要到你必须理解它,学会它,用好它。它最基本的职责就是当页面的访问地址与 Route 上的 path 匹配时,就渲染出对应的 UI 界面。

<Route> 自带三个 render method 和三个 props 。

render methods 分别是:

  • <Route component>
  • <Route render>
  • <Route children>
    每种 render method 都有不同的应用场景,同一个<Route> 应该只使用一种 render method ,大部分情况下你将使用 component 。

props 分别是:

  • match
  • location
  • history
    所有的 render method 无一例外都将被传入这些 props。

component
只有当访问地址和路由匹配时,一个 React component 才会被渲染,此时此组件接受 route props (match, location, history)。
当使用 component 时,router 将使用 React.createElement 根据给定的 component 创建一个新的 React 元素。这意味着如果你使用内联函数(inline function)传值给 component将会产生不必要的重复装载。对于内联渲染(inline rendering), 建议使用 renderprop。


<Route path="/user/:username" component={User} />
const User = ({ match }) => {return <h1>Hello {match.params.username}!</h1>
}

render: func
此方法适用于内联渲染,而且不会产生上文说的重复装载问题。


// 内联渲染
<Route path="/home" render={() => <h1>Home</h1} />// 包装 组合
const FadingRoute = ({ component: Component, ...rest }) => (<Route {...rest} render={props => (<FadeIn><Component {...props} /></FaseIn>)} />
)<FadingRoute path="/cool" component={Something} />

children: func
有时候你可能只想知道访问地址是否被匹配,然后改变下别的东西,而不仅仅是对应的页面。


<ul><ListItemLink to="/somewhere" /><ListItemLink to="/somewhere-ele" />
</ul>const ListItemLink = ({ to, ...rest }) => (<Route path={to} children={({ match }) => (<li className={match ? 'active' : ''}><Link to={to} {...rest} /></li>)}
)

path: string
任何可以被 path-to-regexp解析的有效 URL 路径


<Route path="/users/:id" component={User} />

如果不给path,那么路由将总是匹配。

exact: bool
如果为 true,path 为 '/one' 的路由将不能匹配 '/one/two',反之,亦然。

strict: bool
对路径末尾斜杠的匹配。如果为 true。path 为 '/one/' 将不能匹配 '/one' 但可以匹配 '/one/two'。

如果要确保路由没有末尾斜杠,那么 strict 和
exact 都必须同时为 true

尝试一下


<Link>

为你的应用提供声明式,无障碍导航。

to: string
作用:跳转到指定路径
使用场景:如果只是单纯的跳转就直接用字符串形式的路径。


<Link to="/courses" />

to: object
作用:携带参数跳转到指定路径
作用场景:比如你点击的这个链接将要跳转的页面需要展示此链接对应的内容,又比如这是个支付跳转,需要把商品的价格等信息传递过去。


<Link to={{pathname: '/course',search: '?sort=name',state: { price: 18 }
}} />

replace: bool
为 true 时,点击链接后将使用新地址替换掉上一次访问的地址,什么意思呢,比如:你依次访问 '/one' '/two' '/three' ’/four' 这四个地址,如果回退,将依次回退至 '/three' '/two' '/one' ,这符合我们的预期,假如我们把链接 '/three' 中的 replace 设为 true 时。依次点击 one two three four 然后再回退会发生什么呢?会依次退至 '/three' '/one'! 为此我做了个在线 demo,大家可以调试体会一下 !

另外你能想到这个 prop 的用途是什么呢?有人说在用 路由 做选项卡时候会用到。欢迎留言讨论!

尝试一下


<NavLink>

这是 <Link> 的特殊版,顾名思义这就是为页面导航准备的。因为导航需要有 “激活状态”。

activeClassName: string
导航选中激活时候应用的样式名,默认样式名为 active


<NavLinkto="/about"activeClassName="selected"
>MyBlog</NavLink>

activeStyle: object
如果不想使用样式名就直接写style


<NavLinkto="/about"activeStyle={{ color: 'green', fontWeight: 'bold' }}
>MyBlog</NavLink>

exact: bool
若为 true,只有当访问地址严格匹配时激活样式才会应用

strict: bool
若为 true,只有当访问地址后缀斜杠严格匹配(有或无)时激活样式才会应用

isActive: func
决定导航是否激活,或者在导航激活时候做点别的事情。不管怎样,它不能决定对应页面是否可以渲染。

尝试一下


<Switch>

只渲染出第一个与当前访问地址匹配的 <Route> 或 <Redirect>

思考如下代码,如果你访问 /about,那么组件 About User Nomatch 都将被渲染出来,因为他们对应的路由与访问的地址 /about 匹配。这显然不是我们想要的,我们只想渲染出第一个匹配的路由就可以了,于是 <Switch> 应运而生!


<Route path="/about" component={About}/>
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>

也许你会问,为什么 RR4 机制里不默认匹配第一个符合要求的呢,答:这种设计允许我们将多个 <Route> 组合到应用程序中,例如侧边栏(sidebars),面包屑 等等。

另外,<Switch> 对于转场动画也非常适用,因为被渲染的路由和前一个被渲染的路由处于同一个节点位置!


<Fade><Switch>{/* 用了Switch 这里每次只匹配一个路由,所有只有一个节点。 */}<Route/><Route/></Switch>
</Fade><Fade><Route/><Route/>{/* 不用 Switch 这里可能就会匹配多个路由了,即便匹配不到,也会返回一个null,使动画计算增加了一些麻烦。 */}
</Fade>

children: node
<Switch> 下的子节点只能是 <Route> 或 <Redirect> 元素。只有与当前访问地址匹配的第一个子节点才会被渲染。<Route> 元素用它们的 path 属性匹配,<Redirect> 元素使用它们的 from 属性匹配。如果没有对应的 path 或 from,那么它们将匹配任何当前访问地址。

尝试一下


<Redirect>

<Redirect> 渲染时将导航到一个新地址,这个新地址覆盖在访问历史信息里面的本该访问的那个地址。

to: string
重定向的 URL 字符串

to: object
重定向的 location 对象

push: bool
若为真,重定向操作将会把新地址加入到访问历史记录里面,并且无法回退到前面的页面。

from: string
需要匹配的将要被重定向路径。

尝试一下


Prompt

当用户离开当前页面前做出一些提示。

message: string
当用户离开当前页面时,设置的提示信息。


<Prompt message="确定要离开?" />

message: func
当用户离开当前页面时,设置的回掉函数


<Prompt message={location => (`Are you sue you want to go to ${location.pathname}?`
)} />

when: bool
通过设置一定条件要决定是否启用 Prompt

尝试一下


对象和方法

history

histoty 是 RR4 的两大重要依赖之一(另一个当然是 React 了),在不同的 javascript 环境中, history 以多种能够行驶实现了对会话(session)历史的管理。

我们会经常使用以下术语:

  • "browser history" - history 在 DOM 上的实现,用于支持 HTML5 history API 的浏览器
  • "hash history" - history 在 DOM 上的实现,用于旧版浏览器。
  • "memory history" - history 在内存上的实现,用于测试或非 DOM 环境(例如 React Native)。

history 对象通常具有以下属性和方法:

  • length: number 浏览历史堆栈中的条目数
  • action: string 路由跳转到当前页面执行的动作,分为 PUSH, REPLACE, POP
  • location: object 当前访问地址信息组成的对象,具有如下属性:
    • pathname: string URL路径
    • search: string URL中的查询字符串
    • hash: string URL的 hash 片段
    • state: string 例如执行 push(path, state) 操作时,location 的 state 将被提供到堆栈信息里,state 只有在 browser 和 memory history 有效。
  • push(path, [state]) 在历史堆栈信息里加入一个新条目。
  • replace(path, [state]) 在历史堆栈信息里替换掉当前的条目
  • go(n) 将 history 堆栈中的指针向前移动 n。
  • goBack() 等同于 go(-1)
  • goForward 等同于 go(1)
  • block(prompt) 阻止跳转

history 对象是可变的,因为建议从 <Route> 的 prop 里来获取 location,而不是从 history.location 直接获取。这样可以保证 React 在生命周期中的钩子函数正常执行,例如以下代码:


class Comp extends React.Component {componentWillReceiveProps(nextProps) {// locationChangedconst locationChanged = nextProps.location !== this.props.location// 错误方式,locationChanged 永远为 false,因为history 是可变的const locationChanged = nextProps.history.location !== this.props.history.location}
}

location

location 是指你当前的位置,将要去的位置,或是之前所在的位置


{key: 'sdfad1'pathname: '/about',search: '?name=minooo'hash: '#sdfas',state: {price: 123}
}

在以下情境中可以获取 location 对象

  • 在 Route component 中,以 this.props.location 获取
  • 在 Route render 中,以 ({location}) => () 方式获取
  • 在 Route children 中,以 ({location}) => () 方式获取
  • 在 withRouter 中,以 this.props.location 的方式获取

location 对象不会发生改变,因此可以在生命周期的回调函数中使用 location 对象来查看当前页面的访问地址是否发生改变。这种技巧在获取远程数据以及使用动画时非常有用


componentWillReceiveProps(nextProps) {if (nextProps.location !== this.props.location) {// 已经跳转了!}
}

可以在不同情境中使用 location:

  • <Link to={location} />
  • <NaviveLink to={location} />
  • <Redirect to={location />
  • history.push(location)
  • history.replace(location)

match

match 对象包含了 <Route path> 如何与 URL 匹配的信息,具有以下属性:

  • params: object 路径参数,通过解析 URL 中的动态部分获得键值对
  • isExact: bool 为 true 时,整个 URL 都需要匹配
  • path: string 用来匹配的路径模式,用于创建嵌套的 <Route>
  • url: string URL 匹配的部分,用于嵌套的 <Link>

在以下情境中可以获取 match 对象

  • 在 Route component 中,以 this.props.match获取
  • 在 Route render 中,以 ({match}) => () 方式获取
  • 在 Route children 中,以 ({match}) => () 方式获取
  • 在 withRouter 中,以 this.props.match的方式获取
  • matchPath 的返回值

当一个 Route 没有 path 时,它会匹配一切路径。

初探 React Router 4.0相关推荐

  1. hitchhiker部署_《 Hitchhiker的React Router v4指南》:路由配置的隐藏值

    hitchhiker部署 Welcome to the Hitchhiker's Guide to React Router v4, Part IV! 欢迎来到< React Router v4 ...

  2. 使用React Router以编程方式导航

    通过react-router我可以使用Link元素来创建由react路由器本地处理的链接. 我在内部看到它调用this.context.transitionTo(...) . 我想从下拉列表中进行导航 ...

  3. 从 React Router 谈谈路由的那些事

    React Router 是专为 React 设计的路由解决方案,在使用 React 来开发 SPA (单页应用)项目时,都会需要路由功能,而 React Router 应该是目前使用率最高的. Re ...

  4. React Router 使用教程

    真正学会 React 是一个漫长的过程. 你会发现,它不是一个库,也不是一个框架,而是一个庞大的体系.想要发挥它的威力,整个技术栈都要配合它改造.你要学习一整套解决方案,从后端到前端,都是全新的做法. ...

  5. React Router路由详解

    React Router路由详解 一.基础 1.安装使用 2.React Router 中通用的组件 路由组件 BrowserRouter 和 HashRouter 路径匹配组件: Route 和 S ...

  6. React Router 学习

    本次使用react-router 版本为 5.0.1 本教程前提是你的应用程序是一个web应用程序,使用'react-router-dom'包来实现页面的路由 在React router中有三种类型的 ...

  7. 使用React Router v4的嵌套路由

    React Router v4 introduced a new declarative, component based approach to routing. With that approac ...

  8. React Router入门指南

    by Nader Dabit 纳德·达比特(Nader Dabit) React Router入门指南 (Beginner's Guide to React Router) Or what I wis ...

  9. React 折腾记 - (1) React Router V4 和antd侧边栏的正确关联及动态title的实现

    前言 一如既往,实战出真理. 有兴趣的可以瞧瞧,没兴趣的大佬请止步于此. 免得浪费您的时间 效果图 基于antd的sidebar组件封装 折腾记的技术栈选型 Mobx & mobx-react ...

最新文章

  1. 集合恒等式定律及文氏图
  2. PID1 / 明明的随机数
  3. java byte(字节_【原创】Java中Byte字节流处理的自定义方法库2
  4. 郑州志泽网络科技--SSH模拟试题
  5. Win7系统网页视频无法播放怎么办
  6. android 代码设置textview draw,Android 自定义气泡TextView
  7. 代码管理_阿里巴巴自研代码管理平台技术解密
  8. CentOS7安装Java,java高级面试笔试题
  9. 一文入魂!聊透分布式系统一致性!
  10. 经典:从追MM谈Java的23种设计模式
  11. 一个容易失误的字符串转字符问题
  12. temp不停生成临时文件 win10_Win10系统安装软件提示不能创建临时文件安装中止如何解决...
  13. ios微信浏览器扫码进入页面加载完成失效
  14. 前阿里云CTO章文嵩:怎样做开源才有意义?
  15. vscode调试配置和任务配置
  16. 《一个程序员的奋斗史》读后感:从码农谈起
  17. linux 进程无法启动,linux6.*无法正常启动has进程解决方案
  18. 不一样的蓝牙连接方式——C#程序实现蓝牙通信
  19. 关于runtime error '429'解决方案
  20. Go C画图 CSP-J CSP-S NOIP 信息学奥赛 2023.01.30 测试题

热门文章

  1. putty network error: connection refused
  2. strlen函数,strcat函数,strcpy函数,strncpy函数,strcmp函数
  3. ASP 高亮显示不区分大小写的关键字
  4. VS.NET 2005 Beta2的稳定性太差了:(
  5. H264码流的两种形式:Annex B和AVCC
  6. 类型转换操作符:static_cast, dynamic_cast, const_cast, reinterpret_cast.
  7. java 网络 io流_【015期】JavaSE面试题(十五):网络IO流
  8. 云桌面技术在全国计算机等级考试中发挥护航作用
  9. zabbix 监控 redis
  10. kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式...