本項(xiàng)目Github地址,歡迎star
目錄
這部分API文檔翻譯參考了項(xiàng)目react-router-CN
< BrowserRouter >
<Router> 使用HTML5提供的history API(pushState, replaceState和popstate事件)來同步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。如果你的頁面部署在服務(wù)器的二級子目錄,你需要將basename設(shè)置到此子目錄。 正確的URL格式是前面有一個前導(dǎo)斜杠,但不能有尾部斜杠。
<BrowserRouter basename="/calendar"/>
<Link to="/today"/> // 渲染為 <a href="/calendar/today">
getUserConfirmation: func
當(dāng)導(dǎo)航需要確認(rèn)時執(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時,在導(dǎo)航的過程中整個頁面將會刷新。只有當(dāng)瀏覽器不支持HTML5的 history API 時,才設(shè)置為true。
const supportsHistory = 'pushState' in window.history
<BrowserRouter forceRefresh={!supportsHistory}/>
keyLength: number
location.key的長度。默認(rèn)是6。
<BrowserRouter keyLength={12}/>
children: node
渲染單一子組件(元素)。
< HashRouter >
HashRouter 是一種特定的 <Router>, HashRouter 使用 URL 的 hash (例如:window.location.hash) 來同步UI和URL。
注意:使用 hash 的方式記錄導(dǎo)航歷史不支持 location.key 和 location.state。在以前的版本中,我們?yōu)檫@種行為提供了 shim,但是仍有一些問題我們無法解決。任何依賴此行為的代碼或插件都將無法正常使用。 由于該技術(shù)僅用于支持傳統(tǒng)的瀏覽器,因此在用于瀏覽器時可以使用 <BrowserHistory> 代替。
import { HashRouter } from 'react-router-dom'
<HashRouter>
<App/>
</HashRouter>
basename: string
當(dāng)前位置的基準(zhǔn) URL。正確的 URL 格式是前面有一個前導(dǎo)斜杠,但不能有尾部斜杠。
<HashRouter basename="/calendar"/>
<Link to="/today"/> // renders <a href="#/calendar/today">
getUserConfirmation: func
當(dāng)導(dǎo)航需要確認(rèn)時執(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" - 后面跟一個斜杠,例如 #/ 和 #/sunshine/lollipops
- "noslash" - 后面沒有斜杠,例如 # 和 #sunshine/lollipops
- "hashbang" - Google 風(fēng)格的 “ajax crawlable”,例如 #!/ 和 #!/sunshine/lollipops
默認(rèn)為 "slash"。
children: node
渲染單一子組件(元素)。
< Link >
為您的應(yīng)用提供聲明式的、無障礙導(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 時,點(diǎn)擊鏈接后將使用新地址替換掉訪問歷史記錄里面的原地址。
當(dāng)設(shè)置為 false 時,點(diǎn)擊鏈接后將在原有訪問歷史記錄的基礎(chǔ)上添加一個新的紀(jì)錄。
默認(rèn)為 false。
<Link to="/courses" replace />
< NavLink >
< NavLink >是 < Link > 的一個特定版本, 會在匹配上當(dāng)前 URL 的時候會給已經(jīng)渲染的元素添加樣式參數(shù)
import { NavLink } from 'react-router-dom'
<NavLink to="/about">About</NavLink>
activeClassName: string
當(dāng)元素匹配上當(dāng)前 URL 的時候, 這個類會被賦予給這個元素. 其默認(rèn)值為 active, 這個值會被添加到 className 屬性的后面(追加)
<NavLink
to="/faq"
activeClassName="selected"
>FAQs</NavLink>
activeStyle: object
當(dāng)元素被選中時, 為此元素添加樣式
<NavLink
to="/faq"
activeStyle={{
fontWeight: 'bold',
color: 'red'
}}
>FAQs</NavLink>
exact: bool
當(dāng)值為 true 時, 只有當(dāng)?shù)刂吠耆ヅ?class 和 style 才會應(yīng)用
<NavLink
exact
to="/profile"
>Profile</NavLink
strict: bool
當(dāng)值為 true 時,在確定位置是否與當(dāng)前 URL 匹配時,將考慮位置 pathname 后的斜線 有關(guān)詳細(xì)信息,請參閱< Route strict >文檔。
<NavLink
strict
to="/events/"
>Events</NavLink>
isActive: func
添加用于確定鏈接是否活動的額外邏輯的功能。 如果您想要做的更多,請驗(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)用戶離開當(dāng)前頁的時候做出提示. 當(dāng)你的應(yīng)用處在特定狀態(tài), 此狀態(tài)不希望用戶離開時(例如填寫表格到一半), 你應(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)航離開時,提示用戶的消息。
<Prompt message="Are you sure you want to leave?" />
message: func
會與用戶試圖前往下一個地址(location) 和 action 一起被調(diào)用。
函返回一個字符串用作向用戶提示,或者返回true用作允許過渡。
Prompt
message={location =>
location.pathname.startsWith("/app")
? true
: `Are you sure you want to go to ${location.pathname}?`
}
/>
when: bool
你可以隨時渲染<Prompt>,而不是有條件地在警戒后面渲染它。
- 當(dāng)when={true} 時,禁止導(dǎo)航
- 當(dāng)when={false} 時,允許導(dǎo)航
<Prompt when={formIsHalfFilledOut} message="Are you sure?" />
< MemoryRouter >
< Router > 能在內(nèi)存保存你 “URL” 的歷史紀(jì)錄(并沒有對地址欄讀寫). 在非瀏覽器或者測試環(huán)境比如React Native下很有用。
import { MemoryRouter } from 'react-router'
<MemoryRouter>
<App/>
</MemoryRouter>
initialEntries: array
在歷史棧中的一個 location 數(shù)組. 這些可能會成為含有 { pathname, search, hash, state } 或一些簡單的 URL 字符串的完整的地址對象
<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>時,你必須使用這個選項(xiàng)
keyLength: number
location.key 的長度, 默認(rèn)為 6
<MemoryRouter keyLength={12}/>
children: node
要呈現(xiàn)的 單個子元素。
< Redirect >
渲染<Redirect> 的時候?qū)?dǎo)航到一個新的地址(location)。這個新的地址(location)將會覆蓋在訪問歷史記錄里面的原地址,就像服務(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 時,重定向(redirecting)將會把新地址加入訪問歷史記錄里面,而不是替換掉目前的地址
<Redirect push to="/somewhere/else"/>
from: string
需要被重定向的路徑(pathname)。當(dāng)渲染一個包含在<Switch>里面的<Redirect>的時候,這可以用作匹配一個地址(location)。
<Switch>
<Redirect from='/old-path' to='/new-path'/>
<Route path='/new-path' component={Place}/>
</Switch>
< Route >
想要理解并使用好React Router,最重要的可能就是Route組件了。Route組件主要的作用就是當(dāng)一個location匹配路由的path時,渲染某些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會類似這個樣子:
<div>
<Home/>
<!-- react-empty: 2 -->
</div>
如果應(yīng)用的地址是/news,那么相應(yīng)的UI就會成為這個樣子:
<div>
<!-- react-empty: 1 -->
<NewsFeed/>
</div>
這里的react-empty注釋只是演示了React渲染null的細(xì)節(jié),但對我們具有啟發(fā)性。其實(shí)Route就算是null也會被渲染,只要地址與路由的路徑匹配,組件就會渲染。
Route渲染方法
這三種渲染方法都會獲得相同的三個的屬性:
- match
- location
- history
component
只有在地址匹配的時候React的組件才會被渲染,route props也會隨著一起被渲染。
<Route path="/user/:username" component={User}/>
const User = ({ match }) => {
return <h1>Hello {match.params.username}!</h1>
}
如果你使用component(而不是像下面這樣使用render),路由會根據(jù)指定的組件使用React.createElement來創(chuàng)建一個新的React element。這就意味著如果你提供的是一個內(nèi)聯(lián)的函數(shù)的話會帶來很多意料之外的重新掛載。所以,對于內(nèi)聯(lián)渲染,要使用render屬性(如下所示)。
render: func
這種方式對于內(nèi)聯(lián)渲染和包裝組件卻不引起意料之外的重新掛載特別方便。
使用render屬性,你可以選擇傳一個在地址匹配時被調(diào)用的函數(shù),而不是像使用component屬性那樣得到一個新創(chuàng)建的React element。使用render屬性會獲得跟使用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)先級要比< Route render >高,所以不要在同一個 <Route>中同時使用這兩個屬性。
children: func
有時候你可能想不管地址是否匹配都渲染一些內(nèi)容,這種情況你可以使用children屬性。它與render屬性的工作方式基本一樣,除了它是不管地址匹配與否都會被調(diào)用。
除了在路徑不匹配URL時match的值為null之外,children渲染屬性會獲得與component和render一樣的route props。這就允許你根據(jù)是否匹配路由來動態(tài)地調(diào)整UI了,來看這個例子,如果理由匹配的話就添加一個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>
)}/>
)
這種屬性對于動畫也特別有用:
<Route children={({ match, ...rest }) => (
{/* Animate總會被渲染, 所以你可以使用生命周期來使它的子組件出現(xiàn)
或者隱藏
*/}
<Animate>
{match && <Something {...rest}/>}
</Animate>
)}/>
警告: < Route component >和< Route render > 的優(yōu)先級都比< Route children > 高,所以在同一個<Route>中不要同時使用一個以上的屬性.
path: string
可以是任何path-to-regexp能理解的有效URL。
<Route path="/users/:id" component={User}/>
沒有path屬性的Route 總是會 匹配。
exact: bool
當(dāng)值為true時,則要求路徑與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的時候,有結(jié)尾斜線的路徑只能匹配有斜線的location.pathname,這個值并不會對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)用來匹配。
當(dāng)你需要將< Route >匹配到當(dāng)前history location以外的location時,這非常有用,如動畫過渡示例中所示。
如果< Route >包含在< Switch >中并匹配了傳遞給<Switch>的location(或當(dāng)前history location),那么傳遞給< Route >的location屬性將會被< Switch >使用的所覆蓋。
sensitive: bool
如果該屬性為true,則在匹配時區(qū)分大小寫
path | location.pathname | sensitive | 是否匹配? |
---|---|---|---|
/one | /one | true | yes |
/One | /one | true | no |
/One | /one | false | yes |
< Router >
Router是所有路由組件共用的底層接口,一般我們的應(yīng)用并不會使用這個接口,而是使用高級的路由:
- < BrowserRouter >
- < HashRouter >
- < MemoryRouter >
- < NativeRouter >
- < StaticRouter >
最常見的使用底層的< Router >的情形就是用來與Redux或者M(jìn)obx之類的狀態(tài)管理庫的定制的history保持同步。注意不是說使用狀態(tài)管理庫就必須使用< Router >,它僅用作于深度集成。
import { Router } from 'react-router'
import createBrowserHistory from 'history/createBrowserHistory'
const history = createBrowserHistory()
<Router history={history}>
<App/>
</Router>
history: object
用來導(dǎo)航的history對象.
import createBrowserHistory from 'history/createBrowserHistory'
const customHistory = createBrowserHistory()
<Router history={customHistory}/>
children: node
需要渲染的單一組件。
<Router>
<App/>
</Router>
< StaticRouter >
< Router > 從不會改變地址
當(dāng)用戶實(shí)際上沒有點(diǎn)擊時, 這在服務(wù)端的渲染場景中可能會非常有用, 所以這個地址從來沒有改變. 因此, 稱為: static (靜態(tài)). 當(dāng)您只需要插入一個位置并在渲染輸出上作出斷言時,它也可用于簡單的測試 這里有一個簡單 nodejs 服務(wù) : 為< Redirect >和其他請求的常規(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)該有一個主要的斜杠,但沒有尾部斜杠
<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
一個格式像 { pathname, search, hash, state } 的地址對象
<StaticRouter location={{ pathname: '/bubblegum' }}>
<App/>
</StaticRouter>
context: object
記錄渲染結(jié)果的純JavaScript對象。 見上面的例子
children: node
要呈現(xiàn)的單個子元素。
< Switch >
渲染匹配地址(location)的第一個 < Route > 或者 < Redirect >
這與只使用一堆< Route >有什么不同?
< Switch >的獨(dú)特之處是獨(dú)它僅僅渲染一個路由。相反地,每一個包含匹配地址(location)的< Route >都會被渲染。思考下面的代碼:
<Route path="/about" component={About}/>
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>
如果現(xiàn)在的URL是 /about ,那么 < About >, < User >, 還有 < NoMatch > 都會被渲染,因?yàn)樗鼈兌寂c路徑(path)匹配。這種設(shè)計(jì),允許我們以多種方式將多個 < Route > 組合到我們的應(yīng)用程序中,例如側(cè)欄(sidebars),面包屑(breadcrumbs),bootstrap tabs等等。 然而,偶爾我們只想選擇一個< Route > 來渲染。如果我們現(xiàn)在處于 /about ,我們也不希望匹配 /:user (或者顯示我們的 “404” 頁面 )。以下是使用 Switch 的方法來實(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> 將開始尋找匹配的 <Route>。 <Route path="/about"/> 將被匹配, <Switch> 將停止尋找匹配并渲染<About>。 同樣,如果我們處于 /michael , <User> 將被渲染。
這對于過渡動畫也是起作用的,因?yàn)槠ヅ涞?<Route> 在與前一個相同的位置被渲染。
<Fade>
<Switch>
{/* there will only ever be one child here */}
{/* 這里只會有一個子節(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 */}
{/* 這里總是有兩個子節(jié)點(diǎn),
一個可能會渲染為null, 使計(jì)算過渡增加了一點(diǎn)麻煩 */}
</Fade>
children: node
< Switch > 的所有子節(jié)點(diǎn)應(yīng)為 < Route > 或 < Redirect > 元素。只有匹配當(dāng)前地址(location)的第一個子節(jié)點(diǎn)才會被渲染。< Route > 元素使用它們的 path 屬性匹配,< Redirect > 元素使用它們的 from 屬性匹配。沒有 path 屬性的< Route > 或者 沒有 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對象」請參照 history 包中的內(nèi)容。 History 是 React Router 的兩大重要依賴之一(除去 React 本身),在不同的 Javascript 環(huán)境中,history 以多種形式實(shí)現(xiàn)了對于 session 歷史的管理。
我們會經(jīng)常使用以下術(shù)語:
- 「browser history」 - history 在 DOM 上的實(shí)現(xiàn),經(jīng)常使用于支持 HTML5 history API 的瀏覽器端。
- 「hash history」 - history 在 DOM 上的實(shí)現(xiàn),經(jīng)常使用于舊版本瀏覽器端。
- 「memory history」 - 一種存儲于內(nèi)存的 history 實(shí)現(xiàn),經(jīng)常用于測試或是非 DOM 環(huán)境(例如 React Native)。
history 對象通常會具有以下屬性和方法:
- length -( number 類型)指的是 history 堆棧的數(shù)量。
- action -( string 類型)指的是當(dāng)前的動作(action),例如 PUSH,REPLACE 以及 POP 。
- location -( object類型)是指當(dāng)前的位置(location),location 會具有如下屬性:
- pathname -( string 類型)URL路徑。
- search -( string 類型)URL中的查詢字符串(query string)。
- hash -( string 類型)URL的 hash 分段。
- state -( string 類型)是指 location 中的狀態(tài),例如在 push(path, state) 時,state會描述什么時候 location 被放置到堆棧中等信息。這個 state 只會出現(xiàn)在 browser history 和 memory history 的環(huán)境里。
- push(path, [state]) -( function 類型)在 hisotry 堆棧頂加入一個新的條目。
- replace(path, [state]) -( function 類型)替換在 history 堆棧中的當(dāng)前條目。
- go(n) -( function 類型)將 history 對戰(zhàn)中的指針向前移動 n 。
- goBack() -( function 類型)等同于 go(-1) 。
- goForward() -( function 類型)等同于 go(1) 。
- block(prompt) -( function 類型)阻止跳轉(zhuǎn),(請參照 history 文檔)。
history 是可變的(mutable)
history 對象是可變的,因此我們建議從 <Route> 的 prop里來獲取 location ,而不是從 history.location 直接獲取。這樣做可以保證 React 在生命周期中的鉤子函數(shù)正常執(zhí)行,例如以下代碼:
class Comp extends React.Component {
componentWillReceiveProps(nextProps) {
// locationChanged 變量為 true
const locationChanged = nextProps.location !== this.props.location
// 不正確,locationChanged 變量會 *永遠(yuǎn)* 為 false ,因?yàn)?history 是可變的(mutable)。
const locationChanged = nextProps.history.location !== this.props.history.location
}
}
<Route component={Comp}/>
不同的實(shí)現(xiàn)也許會提供給你額外的屬性,更多詳情請參照 history 文檔。
location
Location 是指你當(dāng)前的位置,下一步打算去的位置,或是你之前所在的位置,形式大概就像這樣:
{
key: 'ac3df4', // 在使用 hashHistory 時,沒有 key
pathname: '/somewhere'
search: '?some=search-string',
hash: '#howdy',
state: {
[userDefined]: true
}
}
你使用以下幾種方式來獲取 location 對象:
- 在 Route component 中,以 this.props.location 的方式獲取,
- 在 Route render 中,以 ({ location }) => () 的方式獲取,
- 在 Route children 中,以 ({ location }) => () 的方式獲取,
- 在 withRouter 中,以 this.props.location 的方式獲取。
你也可以在 history.location 中獲取 location 對象,但是別那么寫,因?yàn)?history 是可變的。更多信息請參見 history 文檔。
location 對象不會發(fā)生改變,因此你可以在生命周期的鉤子函數(shù)中使用 location 對象來查看當(dāng)前頁面的位置是否發(fā)生改變,這種技巧在獲取遠(yuǎn)程數(shù)據(jù)以及使用動畫時非常有用。
對象來查看當(dāng)前頁面的位置是否發(fā)生改變,這種技巧在獲取遠(yuǎn)程數(shù)據(jù)以及使用動畫時非常有用。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
通常情況下,你只需要給一個字符串當(dāng)做 location ,但是,當(dāng)你需要添加一些 location 的狀態(tài)時,你可以對象的形式使用 location 。并且當(dāng)你需要多個 UI ,而這些 UI 取決于歷史時,例如彈出框(modal),使用location 對象會有很大幫助。
/ 通常你只需要這樣使用 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候需要組件去渲染一個其他的 location 而不是本身所處的真實(shí) location,比如使用動畫或是等待跳轉(zhuǎn)時。
match
match 對象包含了 <Route path> 如何與URL匹配的信息。match 對象包含以下屬性:
- params -( object 類型)即路徑參數(shù),通過解析URL中動態(tài)的部分獲得的鍵值對。
- isExact - 當(dāng)為 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 的返回值
當(dāng)一個 Route 沒有 path 時,它會匹配一切路徑,你會匹配到最近的父級。在 withRouter 里也是一樣的。
null matches
即使路徑的路徑與當(dāng)前位置不匹配,< Route >也可以使用子屬性來調(diào)用其子功能。 但在這種情況下,匹配將為null。 能夠在匹配時渲染< Route >的內(nèi)容可能是有用的,但是這種情況會產(chǎn)生一些挑戰(zhàn)。
“解析”URL的默認(rèn)方法是將match.url字符串拼接到“相對”路徑。
`${match.url}/relative-path`
如果在匹配為空時嘗試執(zhí)行此操作,最終會出現(xiàn)TypeError。 這意味著在使用子屬性嘗試連接< Route >內(nèi)的“relative”路徑是不安全的。
當(dāng)你在生成空匹配對象的< Route >中使用沒有path的< Route >時,會出現(xiàn)類似但更微妙的情況。
// location.pathname = '/matches'
<Route path='/does-not-match' children={({ match }) => (
// match === null
<Route render={({ match:pathlessMatch }) => (
// pathlessMatch === ???
)}/>
)}/>
沒有path屬性的< Route >從其父級繼承匹配對象。 如果她們的父匹配為null,那么她們的匹配也將為null。 這意味著
a)任何子路由/鏈接必須是絕對路徑,因?yàn)闆]有要解析的父級
b)父級匹配可以為null的無路徑路由將需要使用子屬性來渲染。
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 下使用, 將會是 req.url
props
第二個參數(shù)是不予匹配的屬性, 他們于匹配 Route 接收的參數(shù)屬性是相同的
{
path, // like /users/:id
strict, // 可選, 默認(rèn) false
exact // 可選, 默認(rèn) false
}
withRouter
你可以通過withRouter的高階組件訪問history對象的屬性和最相似的< Route >的匹配。 每次路由更改時,無論如何是如何渲染的,withRouter將會給封裝的組件傳遞更新的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不會在路由改變時重新渲染,除非她的父組件重新渲染。
靜態(tài)方法和屬性。
封裝的組件的所有非React的靜態(tài)方法和屬性都會被自動的復(fù)制到已連接的組件。
Component.WrappedComponent
封裝的組件作為返回組件上的靜態(tài)屬性WrappedComponent暴露,這個組件可以用于測試。
// 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)} />;
}
}