本項(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)} />;
}
}