react-router

路由用来分发请求,前端是显示页面的,所以它的路由是在找component,后端是提供服务的,它的路由是在找controller

【5种路由方式】

  • BrowserRouter:浏览器的路由方式,在开发中最常使用。
  • HashRouter:在路径前加入#号成为一个哈希值。Hash模式的好处- 是,再也不会因为我们刷新而找不到我们的对应路径了。
  • MemoryRouter:不存储history,所有路由过程保存在内存里,不能进行前进后退,因为地址栏没有发生任何变化。
  • NativeRouter:经常配合ReactNative使用,多用于移动端。
  • StaticRouter:设置静态路由,需要和后台服务器配合设置,比如设置服务端渲染时使用。

【BrowserRouter】

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

<BrowserRouter
  basename={optionalString}
  forceRefresh={optionalBool}
  getUserConfirmation={optionalFunc}
  keyLength={optionalNumber}
>
  <App/>
</BrowserRouter>

1、basename: 当前位置的基准 URL。如果页面部署在服务器的二级(子)目录,需要将basename设置到此子目录。 正确的 URL 格式是前面有一个前导斜杠,但不能有尾部斜杠

<BrowserRouter basename="/calendar"/>

2、getUserConfirmation:当导航需要确认时执行的函数。默认使用 window.confirm

// 使用默认的确认函数
const getConfirmation = (message, callback) => {
  const allowTransition = window.confirm(message)
  callback(allowTransition)
}
<BrowserRouter getUserConfirmation = {getConfirmation} />

3、forceRefresh:当设置为 true 时,在导航的过程中整个页面将会刷新。 只有当浏览器不支持 HTML5 的 history API 时,才设置为 true。

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

4、keyLengthlocation.key的长度。默认是 6。

<BrowserRouter keyLength={12}/>

5、BrowserRouter只能渲染单一子元素。

【Route】
  Route是react-router中最重要的组件,用来匹配请求并渲染相应组件。
  1、path 路径的匹配值,可以包括以下几种特殊符号

:paramName – 匹配一段位于 /、? 或 # 之后的 URL。 命中的部分将被作为一个参数。
() – 在它内部的内容被认为是可选的
* – 匹配任意字符(非贪婪的)直到命中下一个字符或者整个 URL 的末尾,并创建一个 splat 参数

例子如下所示:

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

[注意]Route组件不能像普通组件一样,以属性的形式传递参数,但可以通过path属性来传递,但一定要区分router后面的:_id或:id。

'/category/:_id'

  2、component 要显示的组件

import { BrowserRouter as Router, Route } from 'react-router-dom'

<Router>
  <div>
    <Route exact path="/" component={Home}/>
    <Route path="/news" component={NewsFeed}/>
  </div>
</Router>

  3、render 函数中return的值就是要显示的内容

<Route path="/home" render={() => <div>Home</div>}/>

  4、childrenrender的区别在于,不管有没有匹配,都想显示的内容

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

 [注意]component/render/children只能三个选一个使用

【匹配规则】
  默认地,路由进行宽松匹配。在下面例子中,路由匹配到/one时,既显示组件A,也显示组件B。

<Route  path="/one" component={A}/>
<Route  path="/one/two" component={B}/>

如果要进行确切匹配,则需要添加exact属性。这样,路由匹配到/one时,只显示组件A。

<Route  exact path="/one" component={A}/>
<Route  path="/one/two" component={B}/>

还有一种是严格匹配,即斜杠也必须严格匹配。下面例子中,路由匹配到/one/时,会显示组件A,但匹配到/one时,什么都不会显示

<Route  strict path="/one/" component={A}/>

[注意]严格匹配并不是确切匹配。下面例子中,路由匹配到/one时,即显示组件A,也显示组件B

<Route  strict path="/one" component={A}/>
<Route  path="/one/two" component={B}/>

如果要确切匹配,则需要

<Route  exact strict path="/one" component={A}/>

但是,一般地,strict属性很少使用

【属性】
  Route默认携带三个props:包括matchlocationhistory
  如果使用component,则使用this.props来获取,如果是render,则在回调函数中使用参数(props)=>{}来获取
  1、match
  match包括以下属性:

params 键值对
isExact 是否确切匹配
path 路径中设置的值
url URL中的path值

  2、location
  location中包含如下属性:
  [注意]直接访问location,而不是访问history.location

{
  key: 'ac3df4', // not with HashHistory!
  pathname: '/somewhere'
  search: '?some=search-string',
  hash: '#howdy',
  state: {
    [userDefined]: true
  }
}

通过Link传递的state,可以在location中获取到
[注意]刚开始时,或者直接刷新浏览器,state是没有值的,只有跳转到该链接时,state才有值。再后来,刷新也有值了。
  3、history
  history包含如下属性:

length: history栈的长度
action: 当前的action
location: 当前的location对象

  history包含如下方法:

push()
goBack() = go(-1)
goForward() = go(1)
go() 跳转到 history栈中的哪个enter
replace(path, [state]) 替换history栈中的当前entry
push(path, [state])  添加当前entry到history栈中

【Redirect】
  Redirect将页面导航到新位置,新位置将覆盖history栈中的当前位置,类似于服务器端的重定向(HTTP 3xx)。
  to属性可以是一个字符串,表示跳转的地址。

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>

  to属性也可以是一个对象

<Redirect to={{
  pathname: '/login',
  search: '?utm=your+face',
  state: { referrer: currentLocation }
}}/>

  push属性为true时,表示添加新记录到history栈中,而不是替换当前记录。

<Redirect push to="/somewhere/else"/>

【Link】
  Link是对a标签的封装,提供无刷新的页面跳转。Link标签主要的属性是to属性。

1、一般地,to是一个字符串

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

2、也可以写成对象的形式

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

[注意]在Link里的子组件或同组件的点击事件,最好加上阻止默认行为和阻止冒泡。

<Link>
  <div onclick={}></div>
</Link>
<Link onclick={}>

【NavLink】
  NavLink相对于Link来说,增加了一些样式属性
  activeClassName表示被匹配的a标签的样式名;activeStyle表示被匹配的a标签的样式。

<NavLink
  to="/faq"
  activeClassName="selected"
>FAQs</NavLink>
<NavLink
  to="/faq"
  activeStyle={{
    fontWeight: 'bold',
    color: 'red'
   }}
>FAQs</NavLink>

[注意]linkhistory.push都不支持指向外网地址,如果要跳转到外网,则需要使用window对象下的location对象

【Switch】
  渲染Route或Redirect匹配到的第一个子元素

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

[注意]switch必须直接包括Route,中间不可包含div,否则不生效
跳转。

如果在实现逻辑跳转,可使用如下代码实现:

// utils/history.js
import createBrowserHistory from 'history/createBrowserHistory'
const customHistory = createBrowserHistory()
export default customHistory

引用如下:

import  history  from '@/utils/history'
// 跳转到首页
history.push('/')

要特别注意的是,如果使用utils/history.js,需要使用Router history={history},而不是BrowserRouter
  因为全局只能有一个history实例。 使用import { BrowserRouter as Router }语句,会自动创建一个history实例的,相当于有两个实例,则会出现URL发生变化,刷新页面后,页面才跳转的情况。

import { Router, Route, Switch, Redirect } from 'react-router-dom'
import history from '@/utils/history'

<Router history={history}>
  <Switch>
    <Route path="/login" component={Login} />
    <Route path="/" render={props => {if (sessionStorage.getItem('token') && sessionStorage.getItem('user')) {return <Home {...props} />
        }
        return <Redirect to="/login" />
      }} />
  </Switch>
</Router>

【传参】
  history.push方法也可以携带参数,方法如下

history.push({
  pathname: '/about',
  search: '?the=search',
  state: { some: 'state' }
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容