react-router-dom中link与Navlink

React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 间的同步。

目前react-router最新版本已经到4.0+,因为新的版本是一次非常大的改动,所以这里直接讨论4.0以上版本。

引用

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端应用,只需要引用react-router-dom即可。(如果需要搭配redux则还需引用react-router-redux)

主要组件

<Route>

Route组件主要的作用就是当一个location匹配路由的path时,渲染某些UI,exp:

复制代码
 1 import { BrowserRouter as Router, Route } from 'react-router-dom'
 2 
 3 <Router>
 4   <div>
 5     <Route exact path="/" component={Home}/>
 6     <Route path="/news" component={NewsFeed}/>
 7   </div>
 8 </Router>
 9 // If the location of the app is / then the UI hierarchy will be something like:
10 
11 <div>
12   <Home/>
13   <!-- react-empty: 2 -->
14 </div>
15 // And if the location of the app is /news then the UI hierarchy will be:
16 
17 <div>
18   <!-- react-empty: 1 -->
19   <NewsFeed/>
20 </div>
复制代码

 

<Route> 的三种渲染方式 :

<Route component>  // 只有当访问地址和路由匹配时,一个 React component 才会被渲染,此时此组件接受 route props (match, location, history)
<Route render>    // 此方法适用于内联渲染,不会引起意料之外的重新挂载
<Route children>   // 不管地址匹配与否都会被调用,与render的工作方式基本一样

tips:同一个<Route>中只使用一种渲染方式,多种会被覆盖,优先级为component>render>children。

 

<Route> 的三个属性:

path(string):   // 路由匹配路径。(没有path属性的Route 总是会 匹配);
exact(bool):   // 为true时,则要求路径与location.pathname必须完全匹配;
strict(bool):  // 为true时,有结尾斜线的路径只能匹配有斜线的location.pathname

 

<BrowserRouter>

<Router> 使用 HTML5 提供的 history API (pushStatereplaceState 和 popstate 事件) 来保持 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
作用:渲染单一子元素。

<Link>

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

import { Link } from 'react-router-dom'

<Link to="/about">关于</Link>

属性:

需要跳转到的路径(pathname)或地址(location)。

<Link to="/courses"/>

 

需要跳转到的地址(location)。

复制代码
<Link to={{
  pathname: '/courses',
  search: '?sort=name',
  hash: '#the-hash',
  state: { fromDashboard: true }
}}/>
复制代码

 

当设置为 true 时,点击链接后将使用新地址替换掉访问历史记录里面的原地址。

当设置为 false 时,点击链接后将在原有访问历史记录的基础上添加一个新的纪录。

默认为 false

 

<NavLink>

<NavLink><Link> 的一个特定版本, 会在匹配上当前 URL 的时候会给已经渲染的元素添加样式参数

属性

activeClassName: string

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

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

 

activeStyle: object

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

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

 

exact: bool

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

strict: bool

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

isActive: func

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

<Switch>

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

复制代码
import { Switch, Route } from 'react-router'

<Switch>
  <Route exact path="/" component={Home}/>
  <Route path="/about" component={About}/>
  <Route path="/:user" component={User}/>
  <Redirect to={NoMatch}/>
</Switch>
复制代码

<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

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 在生命周期中的钩子函数正常执行,exg:

复制代码
class Comp extends React.Component {
  componentWillReceiveProps(nextProps) {
    // locationChanged
    const 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=cz'
  hash: '#af01a',
  state: {
    price: 998
  }
}
复制代码

 

在以下情境中可以获取 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 的返回值
posted on 2019-09-24 08:10  萬事順意  阅读(6575)  评论(0编辑  收藏  举报