React-Router v5文檔翻譯之API

本項(xiàng)目Github地址,歡迎star

目錄

這部分API文檔翻譯參考了項(xiàng)目react-router-CN

< BrowserRouter >

<Router> 使用HTML5提供的history API(pushState, replaceState和popstate事件)來(lái)同步UI和URL。

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

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

basename: String

當(dāng)前位置的基準(zhǔn)URL垒探。如果你的頁(yè)面部署在服務(wù)器的二級(jí)子目錄末融,你需要將basename設(shè)置到此子目錄靶壮。 正確的URL格式是前面有一個(gè)前導(dǎo)斜杠展箱,但不能有尾部斜杠。

<BrowserRouter basename="/calendar"/>
<Link to="/today"/> // 渲染為 <a href="/calendar/today">

getUserConfirmation: func

當(dāng)導(dǎo)航需要確認(rèn)時(shí)執(zhí)行的函數(shù)。默認(rèn)使用window.confirm驹沿。

// 使用默認(rèn)的確認(rèn)函數(shù)
const getConfirmation = (message, callback) => {
  const allowTransition = window.confirm(message)
  callback(allowTransition)
}

<BrowserRouter getUserConfirmation={getConfirmation}/>

forceRefresh: bool

當(dāng)設(shè)置為true時(shí),在導(dǎo)航的過(guò)程中整個(gè)頁(yè)面將會(huì)刷新蹈胡。只有當(dāng)瀏覽器不支持HTML5的 history API 時(shí)渊季,才設(shè)置為true。

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

keyLength: number

location.key的長(zhǎng)度罚渐。默認(rèn)是6却汉。

<BrowserRouter keyLength={12}/>

children: node

渲染單一子組件(元素)。

< HashRouter >

HashRouter 是一種特定的 <Router>荷并, HashRouter 使用 URL 的 hash (例如:window.location.hash) 來(lái)同步UI和URL合砂。

注意:使用 hash 的方式記錄導(dǎo)航歷史不支持 location.key 和 location.state言缤。在以前的版本中渊跋,我們?yōu)檫@種行為提供了 shim,但是仍有一些問(wèn)題我們無(wú)法解決眉尸。任何依賴此行為的代碼或插件都將無(wú)法正常使用谈息。 由于該技術(shù)僅用于支持傳統(tǒng)的瀏覽器缘屹,因此在用于瀏覽器時(shí)可以使用 <BrowserHistory> 代替。

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

<HashRouter>
  <App/>
</HashRouter>

basename: string

當(dāng)前位置的基準(zhǔn) URL黎茎。正確的 URL 格式是前面有一個(gè)前導(dǎo)斜杠囊颅,但不能有尾部斜杠。

<HashRouter basename="/calendar"/>
<Link to="/today"/> // renders <a href="#/calendar/today">

getUserConfirmation: func

當(dāng)導(dǎo)航需要確認(rèn)時(shí)執(zhí)行的函數(shù)傅瞻。默認(rèn)使用 window.confirm踢代。

// 使用默認(rèn)的確認(rèn)函數(shù)
const getConfirmation = (message, callback) => {
  const allowTransition = window.confirm(message)
  callback(allowTransition)
}

<HashRouter getUserConfirmation={getConfirmation}/>

hashType: string

window.location.hash 使用的 hash 類型。有如下幾種:

  • "slash" - 后面跟一個(gè)斜杠嗅骄,例如 #/ 和 #/sunshine/lollipops
  • "noslash" - 后面沒(méi)有斜杠胳挎,例如 # 和 #sunshine/lollipops
  • "hashbang" - Google 風(fēng)格的 “ajax crawlable”,例如 #!/ 和 #!/sunshine/lollipops

默認(rèn)為 "slash"溺森。

children: node

渲染單一子組件(元素)慕爬。

< Link >

為您的應(yīng)用提供聲明式的、無(wú)障礙導(dǎo)航屏积。

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

<Link to="/about">關(guān)于</Link>

to: string

需要跳轉(zhuǎn)到的路徑(pathname)或地址(location)医窿。

<Link to="/courses"/>

to: object

需要跳轉(zhuǎn)到的地址(location)。

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

replace: bool

當(dāng)設(shè)置為 true 時(shí)炊林,點(diǎn)擊鏈接后將使用新地址替換掉訪問(wèn)歷史記錄里面的原地址姥卢。
當(dāng)設(shè)置為 false 時(shí),點(diǎn)擊鏈接后將在原有訪問(wèn)歷史記錄的基礎(chǔ)上添加一個(gè)新的紀(jì)錄。
默認(rèn)為 false独榴。

<Link to="/courses" replace />

< NavLink >

< NavLink >是 < Link > 的一個(gè)特定版本, 會(huì)在匹配上當(dāng)前 URL 的時(shí)候會(huì)給已經(jīng)渲染的元素添加樣式參數(shù)

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

<NavLink to="/about">About</NavLink>

activeClassName: string

當(dāng)元素匹配上當(dāng)前 URL 的時(shí)候, 這個(gè)類會(huì)被賦予給這個(gè)元素. 其默認(rèn)值為 active, 這個(gè)值會(huì)被添加到 className 屬性的后面(追加)

<NavLink
  to="/faq"
  activeClassName="selected"
>FAQs</NavLink>

activeStyle: object

當(dāng)元素被選中時(shí), 為此元素添加樣式

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

exact: bool

當(dāng)值為 true 時(shí), 只有當(dāng)?shù)刂吠耆ヅ?class 和 style 才會(huì)應(yīng)用

<NavLink
  exact
  to="/profile"
>Profile</NavLink

strict: bool

當(dāng)值為 true 時(shí)僧叉,在確定位置是否與當(dāng)前 URL 匹配時(shí),將考慮位置 pathname 后的斜線 有關(guān)詳細(xì)信息棺榔,請(qǐng)參閱< Route strict >文檔瓶堕。

<NavLink
  strict
  to="/events/"
>Events</NavLink>

isActive: func

添加用于確定鏈接是否活動(dòng)的額外邏輯的功能。 如果您想要做的更多症歇,請(qǐng)驗(yàn)證鏈接的路徑名是否與當(dāng)前URL的 pathname 匹配郎笆。

// only consider an event active if its event id is an odd number
const oddEvent = (match, location) => {
  if (!match) {
    return false
  }
  const eventID = parseInt(match.params.eventID)
  return !isNaN(eventID) && eventID % 2 === 1
}

<NavLink
  to="/events/123"
  isActive={oddEvent}
>Event 123</NavLink>

< Prompt >

當(dāng)用戶離開(kāi)當(dāng)前頁(yè)的時(shí)候做出提示. 當(dāng)你的應(yīng)用處在特定狀態(tài), 此狀態(tài)不希望用戶離開(kāi)時(shí)(例如填寫(xiě)表格到一半), 你應(yīng)該使用<Prompt>。

import { Prompt } from 'react-router'

<Prompt
  when={formIsHalfFilledOut}
  message="Are you sure you want to leave?"
/>

message: string

當(dāng)用戶嘗試導(dǎo)航離開(kāi)時(shí)当船,提示用戶的消息题画。

<Prompt message="Are you sure you want to leave?" />

message: func

會(huì)與用戶試圖前往下一個(gè)地址(location) 和 action 一起被調(diào)用。
函返回一個(gè)字符串用作向用戶提示德频,或者返回true用作允許過(guò)渡苍息。

Prompt
  message={location =>
    location.pathname.startsWith("/app")
      ? true
      : `Are you sure you want to go to ${location.pathname}?`
  }
/>

when: bool

你可以隨時(shí)渲染<Prompt>,而不是有條件地在警戒后面渲染它壹置。

  • 當(dāng)when={true} 時(shí)竞思,禁止導(dǎo)航
  • 當(dāng)when={false} 時(shí),允許導(dǎo)航
<Prompt when={formIsHalfFilledOut} message="Are you sure?" />

< MemoryRouter >

< Router > 能在內(nèi)存保存你 “URL” 的歷史紀(jì)錄(并沒(méi)有對(duì)地址欄讀寫(xiě)). 在非瀏覽器或者測(cè)試環(huán)境比如React Native下很有用钞护。

import { MemoryRouter } from 'react-router'

<MemoryRouter>
  <App/>
</MemoryRouter>

initialEntries: array

在歷史棧中的一個(gè) location 數(shù)組. 這些可能會(huì)成為含有 { pathname, search, hash, state } 或一些簡(jiǎn)單的 URL 字符串的完整的地址對(duì)象

<MemoryRouter
  initialEntries={[ '/one', '/two', { pathname: '/three' } ]}
  initialIndex={1}
>
  <App/>
</MemoryRouter>

initialIndex: number

initialEntries 數(shù)組中的初始化地址索引

getUserConfirmation: func

用于確認(rèn)導(dǎo)航的函數(shù). 當(dāng)使用<MemoryRouter>直接使用<Prompt>時(shí)盖喷,你必須使用這個(gè)選項(xiàng)

keyLength: number

location.key 的長(zhǎng)度, 默認(rèn)為 6

<MemoryRouter keyLength={12}/>

children: node

要呈現(xiàn)的 單個(gè)子元素。

< Redirect >

渲染<Redirect> 的時(shí)候?qū)?huì)導(dǎo)航到一個(gè)新的地址(location)难咕。這個(gè)新的地址(location)將會(huì)覆蓋在訪問(wèn)歷史記錄里面的原地址课梳,就像服務(wù)端的重定向(HTTP 3XX)一樣

import { Route, Redirect } from 'react-router'

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

to: string

重定向目標(biāo)URL。

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

to: object

重定向目標(biāo)地址(location)余佃。

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

push: bool

當(dāng)設(shè)置為 true 時(shí)暮刃,重定向(redirecting)將會(huì)把新地址加入訪問(wèn)歷史記錄里面,而不是替換掉目前的地址

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

from: string

需要被重定向的路徑(pathname)爆土。當(dāng)渲染一個(gè)包含在<Switch>里面的<Redirect>的時(shí)候椭懊,這可以用作匹配一個(gè)地址(location)。

<Switch>
  <Redirect from='/old-path' to='/new-path'/>
  <Route path='/new-path' component={Place}/>
</Switch>

< Route >

想要理解并使用好React Router步势,最重要的可能就是Route組件了氧猬。Route組件主要的作用就是當(dāng)一個(gè)location匹配路由的path時(shí),渲染某些UI坏瘩。
考慮這樣的代碼:

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

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

如果應(yīng)用的地址是/,那么相應(yīng)的UI會(huì)類似這個(gè)樣子:

<div>
  <Home/>
  <!-- react-empty: 2 -->
</div>

如果應(yīng)用的地址是/news,那么相應(yīng)的UI就會(huì)成為這個(gè)樣子:

<div>
  <!-- react-empty: 1 -->
  <NewsFeed/>
</div>

這里的react-empty注釋只是演示了React渲染null的細(xì)節(jié)盅抚,但對(duì)我們具有啟發(fā)性。其實(shí)Route就算是null也會(huì)被渲染倔矾,只要地址與路由的路徑匹配泉哈,組件就會(huì)渲染。

Route渲染方法

這三種渲染方法都會(huì)獲得相同的三個(gè)的屬性:

  • match
  • location
  • history

component

只有在地址匹配的時(shí)候React的組件才會(huì)被渲染,route props也會(huì)隨著一起被渲染丛晦。

<Route path="/user/:username" component={User}/>

const User = ({ match }) => {
  return <h1>Hello {match.params.username}!</h1>
}

如果你使用component(而不是像下面這樣使用render),路由會(huì)根據(jù)指定的組件使用React.createElement來(lái)創(chuàng)建一個(gè)新的React element。這就意味著如果你提供的是一個(gè)內(nèi)聯(lián)的函數(shù)的話會(huì)帶來(lái)很多意料之外的重新掛載提陶。所以烫沙,對(duì)于內(nèi)聯(lián)渲染,要使用render屬性(如下所示)隙笆。

render: func

這種方式對(duì)于內(nèi)聯(lián)渲染和包裝組件卻不引起意料之外的重新掛載特別方便锌蓄。
使用render屬性,你可以選擇傳一個(gè)在地址匹配時(shí)被調(diào)用的函數(shù)撑柔,而不是像使用component屬性那樣得到一個(gè)新創(chuàng)建的React element瘸爽。使用render屬性會(huì)獲得跟使用component屬性一樣的route props。

// 便捷的行內(nèi)渲染
<Route path="/home" render={() => <div>Home</div>}/>

// 包裝/合成
const FadingRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    <FadeIn>
      <Component {...props}/>
    </FadeIn>
  )}/>
)

<FadingRoute path="/cool" component={Something}/>

警告: < Route component >的優(yōu)先級(jí)要比< Route render >高铅忿,所以不要在同一個(gè) <Route>中同時(shí)使用這兩個(gè)屬性剪决。

children: func

有時(shí)候你可能想不管地址是否匹配都渲染一些內(nèi)容,這種情況你可以使用children屬性檀训。它與render屬性的工作方式基本一樣柑潦,除了它是不管地址匹配與否都會(huì)被調(diào)用。
除了在路徑不匹配URL時(shí)match的值為null之外峻凫,children渲染屬性會(huì)獲得與component和render一樣的route props渗鬼。這就允許你根據(jù)是否匹配路由來(lái)動(dòng)態(tài)地調(diào)整UI了,來(lái)看這個(gè)例子荧琼,如果理由匹配的話就添加一個(gè)active類:

<ul>
  <ListItemLink to="/somewhere"/>
  <ListItemLink to="/somewhere-else"/>
</ul>

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

這種屬性對(duì)于動(dòng)畫(huà)也特別有用:

<Route children={({ match, ...rest }) => (
  {/* Animate總會(huì)被渲染, 所以你可以使用生命周期來(lái)使它的子組件出現(xiàn)
    或者隱藏
  */}
  <Animate>
    {match && <Something {...rest}/>}
  </Animate>
)}/>

警告: < Route component >和< Route render > 的優(yōu)先級(jí)都比< Route children > 高譬胎,所以在同一個(gè)<Route>中不要同時(shí)使用一個(gè)以上的屬性.

path: string

可以是任何path-to-regexp能理解的有效URL。

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

沒(méi)有path屬性的Route 總是會(huì) 匹配命锄。

exact: bool

當(dāng)值為true時(shí)堰乔,則要求路徑與location.pathname必須 完全 匹配。

<Route exact path="/one" component={About}/>
路徑 location.pathname exact 是否匹配?
/one /one/two true
/one /one/two false

strict: bool

當(dāng)設(shè)為true的時(shí)候累舷,有結(jié)尾斜線的路徑只能匹配有斜線的location.pathname浩考,這個(gè)值并不會(huì)對(duì)location.pathname中有其他的片段有影響。

<Route strict path="/one/" component={About}/>
路徑 location.pathname 是否匹配?
/one/ /one
/one/ /one/
/one/ /one/two

警告: stict可以強(qiáng)制location.pathname不包含結(jié)尾的斜線被盈,但是要做到這點(diǎn)必須把strict和exect都設(shè)置為true析孽。

<Route exact strict path="/one" component={About}/>
路徑 location.pathname 是否匹配?
/one /one
/one /one/
/one /one/two

location: object

< Route >元素嘗試將路徑path當(dāng)前history location(通常是當(dāng)前瀏覽器URL)進(jìn)行匹配。 除此之外只怎,具有不同pathname的location也可以被傳統(tǒng)用來(lái)匹配袜瞬。

當(dāng)你需要將< Route >匹配到當(dāng)前history location以外的location時(shí),這非常有用身堡,如動(dòng)畫(huà)過(guò)渡示例中所示邓尤。

如果< Route >包含在< Switch >中并匹配了傳遞給<Switch>的location(或當(dāng)前history location),那么傳遞給< Route >的location屬性將會(huì)被< Switch >使用的所覆蓋。

sensitive: bool

如果該屬性為true,則在匹配時(shí)區(qū)分大小寫(xiě)

path location.pathname sensitive 是否匹配?
/one /one true yes
/One /one true no
/One /one false yes

< Router >

Router是所有路由組件共用的底層接口汞扎,一般我們的應(yīng)用并不會(huì)使用這個(gè)接口季稳,而是使用高級(jí)的路由:

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

最常見(jiàn)的使用底層的< Router >的情形就是用來(lái)與Redux或者M(jìn)obx之類的狀態(tài)管理庫(kù)的定制的history保持同步。注意不是說(shuō)使用狀態(tài)管理庫(kù)就必須使用< Router >澈魄,它僅用作于深度集成景鼠。

import { Router } from 'react-router'
import createBrowserHistory from 'history/createBrowserHistory'

const history = createBrowserHistory()

<Router history={history}>
  <App/>
</Router>

history: object

用來(lái)導(dǎo)航的history對(duì)象.

import createBrowserHistory from 'history/createBrowserHistory'

const customHistory = createBrowserHistory()
<Router history={customHistory}/>

children: node

需要渲染的單一組件。

<Router>
  <App/>
</Router>

< StaticRouter >

< Router > 從不會(huì)改變地址
當(dāng)用戶實(shí)際上沒(méi)有點(diǎn)擊時(shí), 這在服務(wù)端的渲染場(chǎng)景中可能會(huì)非常有用, 所以這個(gè)地址從來(lái)沒(méi)有改變. 因此, 稱為: static (靜態(tài)). 當(dāng)您只需要插入一個(gè)位置并在渲染輸出上作出斷言時(shí)痹扇,它也可用于簡(jiǎn)單的測(cè)試 這里有一個(gè)簡(jiǎn)單 nodejs 服務(wù) : 為< Redirect >和其他請(qǐng)求的常規(guī)HTML發(fā)送302狀態(tài)代碼:

import { createServer } from 'http'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router'

createServer((req, res) => {

  // This context object contains the results of the render
  const context = {}

  const html = ReactDOMServer.renderToString(
    <StaticRouter location={req.url} context={context}>
      <App/>
    </StaticRouter>
  )

  // context.url will contain the URL to redirect to if a <Redirect> was used
  if (context.url) {
    res.writeHead(302, {
      Location: context.url
    })
    res.end()
  } else {
    res.write(html)
    res.end()
  }
}).listen(3000)

basename: string

所有地址的基本 URL . 正確格式化的基本名稱應(yīng)該有一個(gè)主要的斜杠铛漓,但沒(méi)有尾部斜杠

<StaticRouter basename="/calendar">
  <Link to="/today"/> // renders <a href="/calendar/today">
</StaticRouter>

location: string

服務(wù)器收到的 URL, 在 node 服務(wù)上可能是 req.url

<StaticRouter location={req.url}>
  <App/>
</StaticRouter>

location: object

一個(gè)格式像 { pathname, search, hash, state } 的地址對(duì)象

<StaticRouter location={{ pathname: '/bubblegum' }}>
  <App/>
</StaticRouter>

context: object

記錄渲染結(jié)果的純JavaScript對(duì)象。 見(jiàn)上面的例子

children: node

要呈現(xiàn)的單個(gè)子元素鲫构。

< Switch >

渲染匹配地址(location)的第一個(gè) < Route > 或者 < Redirect >
這與只使用一堆< Route >有什么不同浓恶?
< Switch >的獨(dú)特之處是獨(dú)它僅僅渲染一個(gè)路由。相反地结笨,每一個(gè)包含匹配地址(location)的< Route >都會(huì)被渲染包晰。思考下面的代碼:

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

如果現(xiàn)在的URL是 /about ,那么 < About >, < User >, 還有 < NoMatch > 都會(huì)被渲染禀梳,因?yàn)樗鼈兌寂c路徑(path)匹配杜窄。這種設(shè)計(jì),允許我們以多種方式將多個(gè) < Route > 組合到我們的應(yīng)用程序中算途,例如側(cè)欄(sidebars)塞耕,面包屑(breadcrumbs),bootstrap tabs等等嘴瓤。 然而扫外,偶爾我們只想選擇一個(gè)< Route > 來(lái)渲染。如果我們現(xiàn)在處于 /about 廓脆,我們也不希望匹配 /:user (或者顯示我們的 “404” 頁(yè)面 )筛谚。以下是使用 Switch 的方法來(lái)實(shí)現(xiàn):

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

現(xiàn)在,如果我們處于 /about, <Switch> 將開(kāi)始尋找匹配的 <Route>停忿。 <Route path="/about"/> 將被匹配驾讲, <Switch> 將停止尋找匹配并渲染<About>。 同樣席赂,如果我們處于 /michael 吮铭, <User> 將被渲染。

這對(duì)于過(guò)渡動(dòng)畫(huà)也是起作用的颅停,因?yàn)槠ヅ涞?<Route> 在與前一個(gè)相同的位置被渲染谓晌。

<Fade>
  <Switch>
    {/* there will only ever be one child here */}
    {/* 這里只會(huì)有一個(gè)子節(jié)點(diǎn) */}
    <Route/>
    <Route/>
  </Switch>
</Fade>

<Fade>
  <Route/>
  <Route/>
  {/* there will always be two children here,
      one might render null though, making transitions
      a bit more cumbersome to work out */}
   {/* 這里總是有兩個(gè)子節(jié)點(diǎn),
      一個(gè)可能會(huì)渲染為null, 使計(jì)算過(guò)渡增加了一點(diǎn)麻煩 */}    
</Fade>

children: node

< Switch > 的所有子節(jié)點(diǎn)應(yīng)為 < Route > 或 < Redirect > 元素。只有匹配當(dāng)前地址(location)的第一個(gè)子節(jié)點(diǎn)才會(huì)被渲染癞揉。< Route > 元素使用它們的 path 屬性匹配纸肉,< Redirect > 元素使用它們的 from 屬性匹配溺欧。沒(méi)有 path 屬性的< Route > 或者 沒(méi)有 from 屬性的 < Redirect > 將總是可以匹配當(dāng)前的地址(location)

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

  <Route path="/users" component={Users}/>
  <Redirect from="/accounts" to="/users"/>

  <Route component={NoMatch}/>
</Switch>

history

本文檔中的「history」以及「history對(duì)象」請(qǐng)參照 history 包中的內(nèi)容。 History 是 React Router 的兩大重要依賴之一(除去 React 本身)柏肪,在不同的 Javascript 環(huán)境中姐刁,history 以多種形式實(shí)現(xiàn)了對(duì)于 session 歷史的管理。
我們會(huì)經(jīng)常使用以下術(shù)語(yǔ):

  • 「browser history」 - history 在 DOM 上的實(shí)現(xiàn)烦味,經(jīng)常使用于支持 HTML5 history API 的瀏覽器端龙填。
  • 「hash history」 - history 在 DOM 上的實(shí)現(xiàn),經(jīng)常使用于舊版本瀏覽器端拐叉。
  • 「memory history」 - 一種存儲(chǔ)于內(nèi)存的 history 實(shí)現(xiàn),經(jīng)常用于測(cè)試或是非 DOM 環(huán)境(例如 React Native)扇商。

history 對(duì)象通常會(huì)具有以下屬性和方法:

  • length -( number 類型)指的是 history 堆棧的數(shù)量凤瘦。
  • action -( string 類型)指的是當(dāng)前的動(dòng)作(action),例如 PUSH案铺,REPLACE 以及 POP 蔬芥。
  • location -( object類型)是指當(dāng)前的位置(location),location 會(huì)具有如下屬性:
    • pathname -( string 類型)URL路徑控汉。
    • search -( string 類型)URL中的查詢字符串(query string)笔诵。
    • hash -( string 類型)URL的 hash 分段。
    • state -( string 類型)是指 location 中的狀態(tài)姑子,例如在 push(path, state) 時(shí)乎婿,state會(huì)描述什么時(shí)候 location 被放置到堆棧中等信息。這個(gè) state 只會(huì)出現(xiàn)在 browser history 和 memory history 的環(huán)境里街佑。
  • push(path, [state]) -( function 類型)在 hisotry 堆棧頂加入一個(gè)新的條目谢翎。
  • replace(path, [state]) -( function 類型)替換在 history 堆棧中的當(dāng)前條目。
  • go(n) -( function 類型)將 history 對(duì)戰(zhàn)中的指針向前移動(dòng) n 沐旨。
  • goBack() -( function 類型)等同于 go(-1) 森逮。
  • goForward() -( function 類型)等同于 go(1) 。
  • block(prompt) -( function 類型)阻止跳轉(zhuǎn)磁携,(請(qǐng)參照 history 文檔)褒侧。

history 是可變的(mutable)

history 對(duì)象是可變的,因此我們建議從 <Route> 的 prop里來(lái)獲取 location 谊迄,而不是從 history.location 直接獲取闷供。這樣做可以保證 React 在生命周期中的鉤子函數(shù)正常執(zhí)行,例如以下代碼:

class Comp extends React.Component {
  componentWillReceiveProps(nextProps) {
    // locationChanged 變量為 true
    const locationChanged = nextProps.location !== this.props.location

    // 不正確鳞上,locationChanged 變量會(huì) *永遠(yuǎn)* 為 false 这吻,因?yàn)?history 是可變的(mutable)。
    const locationChanged = nextProps.history.location !== this.props.history.location
  }
}

<Route component={Comp}/>

不同的實(shí)現(xiàn)也許會(huì)提供給你額外的屬性篙议,更多詳情請(qǐng)參照 history 文檔唾糯。

location

Location 是指你當(dāng)前的位置怠硼,下一步打算去的位置,或是你之前所在的位置移怯,形式大概就像這樣:

{
  key: 'ac3df4', // 在使用 hashHistory 時(shí)香璃,沒(méi)有 key
  pathname: '/somewhere'
  search: '?some=search-string',
  hash: '#howdy',
  state: {
    [userDefined]: true
  }
}

你使用以下幾種方式來(lái)獲取 location 對(duì)象:

  • 在 Route component 中,以 this.props.location 的方式獲取舟误,
  • 在 Route render 中葡秒,以 ({ location }) => () 的方式獲取,
  • 在 Route children 中嵌溢,以 ({ location }) => () 的方式獲取眯牧,
  • 在 withRouter 中,以 this.props.location 的方式獲取赖草。

你也可以在 history.location 中獲取 location 對(duì)象学少,但是別那么寫(xiě),因?yàn)?history 是可變的秧骑。更多信息請(qǐng)參見(jiàn) history 文檔版确。

location 對(duì)象不會(huì)發(fā)生改變,因此你可以在生命周期的鉤子函數(shù)中使用 location 對(duì)象來(lái)查看當(dāng)前頁(yè)面的位置是否發(fā)生改變乎折,這種技巧在獲取遠(yuǎn)程數(shù)據(jù)以及使用動(dòng)畫(huà)時(shí)非常有用绒疗。

對(duì)象來(lái)查看當(dāng)前頁(yè)面的位置是否發(fā)生改變,這種技巧在獲取遠(yuǎn)程數(shù)據(jù)以及使用動(dòng)畫(huà)時(shí)非常有用骂澄。componentWillReceiveProps(nextProps) {
  if (nextProps.location !== this.props.location) {
    // 已經(jīng)跳轉(zhuǎn)了吓蘑!
  }
}

你可以在不同環(huán)境中使用 location :

  • Web Link to
  • Native Link to
  • Redirect to
  • history.push
  • history.replace
    通常情況下,你只需要給一個(gè)字符串當(dāng)做 location 酗洒,但是士修,當(dāng)你需要添加一些 location 的狀態(tài)時(shí),你可以對(duì)象的形式使用 location 樱衷。并且當(dāng)你需要多個(gè) UI 棋嘲,而這些 UI 取決于歷史時(shí),例如彈出框(modal)矩桂,使用location 對(duì)象會(huì)有很大幫助沸移。
/ 通常你只需要這樣使用 location
<Link to="/somewhere"/>

// 但是你同樣可以這么用
const location = {
  pathname: '/somewhere'
  state: { fromDashboard: true }
}

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

最后,你可以把 location 傳入一下組件:

  • Route
  • Switch
    這樣做可以讓組件不使用路由狀態(tài)(router state)中的真實(shí) location侄榴,因?yàn)槲覀冇袝r(shí)候需要組件去渲染一個(gè)其他的 location 而不是本身所處的真實(shí) location雹锣,比如使用動(dòng)畫(huà)或是等待跳轉(zhuǎn)時(shí)。

match

match 對(duì)象包含了 <Route path> 如何與URL匹配的信息癞蚕。match 對(duì)象包含以下屬性:

  • params -( object 類型)即路徑參數(shù)蕊爵,通過(guò)解析URL中動(dòng)態(tài)的部分獲得的鍵值對(duì)。
  • isExact - 當(dāng)為 true 時(shí)桦山,整個(gè)URL都需要匹配攒射。
  • path -( string 類型)用來(lái)做匹配的路徑格式醋旦。在需要嵌套 <Route> 的時(shí)候用到。
  • url -( string 類型)URL匹配的部分会放,在需要嵌套 <Link> 的時(shí)候會(huì)用到饲齐。
    你可以在以下地方獲取 match 對(duì)象:
  • 在 Route component 中,以 this.props.match 方式咧最。
  • 在 Route render 中捂人,以 ({ match }) => () 方式。
  • 在 Route children 中矢沿,以 ({ match }) => () 方式
  • 在 withRouter 中滥搭,以 this.props.match 方式
  • matchPath 的返回值
    當(dāng)一個(gè) Route 沒(méi)有 path 時(shí),它會(huì)匹配一切路徑捣鲸,你會(huì)匹配到最近的父級(jí)论熙。在 withRouter 里也是一樣的。

null matches

即使路徑的路徑與當(dāng)前位置不匹配摄狱,< Route >也可以使用子屬性來(lái)調(diào)用其子功能。 但在這種情況下无午,匹配將為null媒役。 能夠在匹配時(shí)渲染< Route >的內(nèi)容可能是有用的,但是這種情況會(huì)產(chǎn)生一些挑戰(zhàn)宪迟。

“解析”URL的默認(rèn)方法是將match.url字符串拼接到“相對(duì)”路徑酣衷。

`${match.url}/relative-path`

如果在匹配為空時(shí)嘗試執(zhí)行此操作,最終會(huì)出現(xiàn)TypeError次泽。 這意味著在使用子屬性嘗試連接< Route >內(nèi)的“relative”路徑是不安全的穿仪。

當(dāng)你在生成空匹配對(duì)象的< Route >中使用沒(méi)有path的< Route >時(shí),會(huì)出現(xiàn)類似但更微妙的情況意荤。

// location.pathname = '/matches'
<Route path='/does-not-match' children={({ match }) => (
  // match === null
  <Route render={({ match:pathlessMatch }) => (
    // pathlessMatch === ???
  )}/>
)}/>

沒(méi)有path屬性的< Route >從其父級(jí)繼承匹配對(duì)象啊片。 如果她們的父匹配為null,那么她們的匹配也將為null玖像。 這意味著
a)任何子路由/鏈接必須是絕對(duì)路徑紫谷,因?yàn)闆](méi)有要解析的父級(jí)
b)父級(jí)匹配可以為null的無(wú)路徑路由將需要使用子屬性來(lái)渲染。

matchPath

這允許您使用與一樣使用的相同的代碼捐寥,除了在正常渲染循環(huán)之外笤昨,例如在服務(wù)器上渲染之前收集數(shù)據(jù)依賴關(guān)系

import { matchPath } from 'react-router'

const match = matchPath('/users/123', {
  path: '/users/:id'
  exact: true,
  strict: false
})

pathname

第一參數(shù)是你想要匹配的 pathname, 如果你正在服務(wù)端的 nodos.js 下使用, 將會(huì)是 req.url

props

第二個(gè)參數(shù)是不予匹配的屬性, 他們于匹配 Route 接收的參數(shù)屬性是相同的

{
  path, // like /users/:id
  strict, // 可選, 默認(rèn) false
  exact // 可選, 默認(rèn) false
}

withRouter

你可以通過(guò)withRouter的高階組件訪問(wèn)history對(duì)象的屬性和最相似的< Route >的匹配。 每次路由更改時(shí)握恳,無(wú)論如何是如何渲染的瞒窒,withRouter將會(huì)給封裝的組件傳遞更新的match,location 和 history屬性。

mport React from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router";

// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
  static propTypes = {
    match: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  };

  render() {
    const { match, location, history } = this.props;

    return <div>You are now at {location.pathname}</div>;
  }
}

// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation);

重要提醒

withRouter不追蹤location的更改乡洼,而是在從< Router >組件傳播出去的location改變后重新渲染崇裁,這意味著withRouter不會(huì)在路由改變時(shí)重新渲染匕坯,除非她的父組件重新渲染。

靜態(tài)方法和屬性寇壳。

封裝的組件的所有非React的靜態(tài)方法和屬性都會(huì)被自動(dòng)的復(fù)制到已連接的組件醒颖。

Component.WrappedComponent

封裝的組件作為返回組件上的靜態(tài)屬性WrappedComponent暴露,這個(gè)組件可以用于測(cè)試壳炎。

// MyComponent.js
export default withRouter(MyComponent)

// MyComponent.test.js
import MyComponent from './MyComponent'
render(<MyComponent.WrappedComponent location={{...}} ... />)

wrappedComponentRef: func

作為引用的屬性被傳遞給封裝的組件的函數(shù)

class Container extends React.Component {
  componentDidMount() {
    this.component.doSomething();
  }

  render() {
    return <MyComponent wrappedComponentRef={c => (this.component = c)} />;
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末泞歉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子匿辩,更是在濱河造成了極大的恐慌腰耙,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铲球,死亡現(xiàn)場(chǎng)離奇詭異挺庞,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)稼病,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)选侨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人然走,你說(shuō)我怎么就攤上這事援制。” “怎么了芍瑞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵晨仑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我拆檬,道長(zhǎng)洪己,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任竟贯,我火速辦了婚禮答捕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘屑那。我一直安慰自己噪珊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布齐莲。 她就那樣靜靜地躺著痢站,像睡著了一般。 火紅的嫁衣襯著肌膚如雪选酗。 梳的紋絲不亂的頭發(fā)上阵难,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音芒填,去河邊找鬼呜叫。 笑死空繁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的朱庆。 我是一名探鬼主播盛泡,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼娱颊!你這毒婦竟也來(lái)了傲诵?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤箱硕,失蹤者是張志新(化名)和其女友劉穎拴竹,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體剧罩,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡栓拜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惠昔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幕与。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖镇防,靈堂內(nèi)的尸體忽然破棺而出纽门,到底是詐尸還是另有隱情,我是刑警寧澤营罢,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站饼齿,受9級(jí)特大地震影響饲漾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缕溉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一考传、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧证鸥,春花似錦僚楞、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至鸟蜡,卻和暖如春膜赃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背揉忘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工跳座, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留端铛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓疲眷,卻偏偏與公主長(zhǎng)得像禾蚕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狂丝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351