React-router v4教程

在這個(gè)教程里楷怒,我們會(huì)從一個(gè)例子React應(yīng)用開始學(xué)習(xí)react-router-dom蛋勺。其中你會(huì)學(xué)習(xí)如何使用LinkNavLink等來(lái)實(shí)現(xiàn)跳轉(zhuǎn)鸠删,Switchexact實(shí)現(xiàn)排他路由和瀏覽器路徑歷史抱完。

也許學(xué)習(xí)react-router最好的辦法就是用react-router-dom v4來(lái)寫一個(gè)多頁(yè)的react應(yīng)用。這個(gè)react應(yīng)用會(huì)包含登錄刃泡、注冊(cè)巧娱、首頁(yè)碉怔、聯(lián)系人等頁(yè)面。但是禁添,首先讓我們來(lái)看一下react router v4的概念眨层,以及它與v3有什么不同的地方。

React router v4 vs v3

v4是react router的一次重寫上荡,所以和v3有很多不同的地方趴樱。主要有:

  • 在react router v4里,路由不再是集中在一起的酪捡。它成了應(yīng)用布局叁征、UI的一部分。
  • 瀏覽器用的router在react-router-dom里逛薇。所以捺疼,瀏覽器里使用的時(shí)候只需要import react-router-dom就可以。
  • 新的概念BrowerRouterHashRouter永罚。他們各自服務(wù)于不同的情景下啤呼。詳見下文。
  • 不在使用{props.children}來(lái)處理嵌套的路由呢袱。
  • v4的路由默認(rèn)不再排他官扣,會(huì)有多個(gè)匹配。而v3是默認(rèn)排他的羞福,只會(huì)有一個(gè)匹配被使用惕蹄。

react-router-dom是react-router中用于瀏覽器的。react-router被分為一下幾部分:

  • react-router是瀏覽器和原生應(yīng)用的通用部分治专。
  • react-router-dom是用于瀏覽器的卖陵。
  • react-router-native是用于原生應(yīng)用的。

React-router vs react-router-dom vs react-router-native

react-router是核心部分张峰。react-router-dom提供了瀏覽器使用需要的定制組件泪蔫。react-router-native則專門提供了在原生移動(dòng)應(yīng)用中需要用到的部分。所以喘批,如果在本例中實(shí)現(xiàn)瀏覽器開發(fā)就只需要安裝react-router-dom撩荣。

安裝

如上所說,我們使用react開發(fā)web應(yīng)用谤祖,所以只需要安裝react-router-dom婿滓。

  npm install react-router-dom --save

理解和使用react-router

  • BrowserRouter老速,這是對(duì)Router接口的實(shí)現(xiàn)粥喜。使得頁(yè)面和瀏覽器的history保持一致。如:window.location橘券。
  • HashRouter额湘,和上面的一樣卿吐,只是使用的是url的hash部分,比如:window.location.hash锋华。
  • MemoryRouter嗡官,
  • NativeRouter,處理react native內(nèi)的路由毯焕。
  • StaticRouter衍腥,處理靜態(tài)路由,和v3一樣纳猫。

BrowserRouter vs HashRouter

在react-router的各種router中婆咸,<BrowserRouter><HashRouter>是可以在瀏覽器中使用的。如果你使用的是一個(gè)非靜態(tài)的站點(diǎn)芜辕、要處理各種不同的url那么你就需要使用BrowserRouter尚骄。相反的如果你的server只處理靜態(tài)的url,那么就使用HashRouter侵续。

理解和使用Route

<Route>組件是react router v4里最有用的組件倔丈。背后的使用哲學(xué)也很簡(jiǎn)單,無(wú)論何時(shí)你需要在匹配某個(gè)路徑的時(shí)候繪制一個(gè)組件状蜗,那么就可以使用Route組件需五。

Route組件可以使用如下的屬性:

  • path屬性,字符串類型轧坎,它的值就是用來(lái)匹配url的警儒。
  • component屬性,它的值是一個(gè)組件眶根。在path匹配成功之后會(huì)繪制這個(gè)組件蜀铲。
  • exact屬性,這個(gè)屬性用來(lái)指明這個(gè)路由是不是排他的匹配属百。
  • strict屬性记劝, 這個(gè)屬性指明路徑只匹配以斜線結(jié)尾的路徑。

還有其他的一些屬性族扰,可以用來(lái)代替component屬性厌丑。

  • render屬性,一個(gè)返回React組件的方法渔呵。傳說中的rencer-prop就是從這里來(lái)的怒竿。
  • children屬性,返回一個(gè)React組件的方法扩氢。只不過這個(gè)總是會(huì)繪制耕驰,即使沒有匹配的路徑的時(shí)候。

多數(shù)的時(shí)候是用component屬性就可以滿足录豺。但是朦肘,某些情況下你不得不使用renderchildren屬性饭弓。

  • match
  • location
  • history

如:
使用組件:

<Route exact path="/" component={HomePage} />

使用render屬性實(shí)現(xiàn)內(nèi)聯(lián)繪制:

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

來(lái)看哥更復(fù)雜的:

const FadingRoute = ({ component, ...rest }) => (
  <Route {...rest} render={(props) => (
    <FadeIn>
      <componnet {...props} />
    </FadeIn>
  )} />
)

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

使用children

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

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

更多關(guān)于react-router v4如何匹配路徑的內(nèi)容,請(qǐng)移步這里媒抠。

URL / Path / Route的參數(shù)

通常情況下弟断,我們都會(huì)在路徑里添加參數(shù)。這樣方便在不同的組件之間傳遞一些必要的數(shù)據(jù)趴生。那么我們?nèi)绾尾拍塬@取到這些傳遞的參數(shù)阀趴,并傳遞給組件中呢?我們只需要在路徑的最后加上/:param苍匆。如:

<Route path="/:param1" component={HomePage} />

const HomePage = ({match}) => (
  <div>
    <h1> parameter => {match.params.param1}
  </div>
);

一旦有路徑可以匹配成功舍咖,那么就會(huì)穿件一個(gè)擁有如下屬性的對(duì)象,并傳入繪制的組件里:

  • url: 匹配的url锉桑。
  • path:就是path排霉。
  • isExact:如果path和當(dāng)前的widnow.location的path部分完全相同的話。
  • params:在URL里包含的參數(shù)民轴。

理解并使用Link

Link是react router v4特有的一個(gè)組件攻柠。是用來(lái)代替上一版的anchor link。使用Link可以在React應(yīng)用的不同頁(yè)面之間跳轉(zhuǎn)后裸。與unclor會(huì)重新加載整個(gè)頁(yè)面不同瑰钮,Link只會(huì)重新加載頁(yè)面里和當(dāng)前url可以匹配的部分。

Link組件需要用到to屬性微驶,這個(gè)屬性的值就是react router要跳轉(zhuǎn)到的地址浪谴。如:

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

const Nav = () => (
  <Link to '/'>Home</Link>
);

當(dāng)被點(diǎn)擊的時(shí)候,會(huì)跳轉(zhuǎn)到路徑:/因苹。

to屬性的值可以是一個(gè)字符串苟耻,也可以是一個(gè)location(pathname, hash, state和search)對(duì)象。比如:

<Link to{{
  pathname: '/me',
  search: '?sort=asc',
  hash: '#hash',
  state: { fromHome: true }
}} />

Link也可以使用replace屬性扶檐,如果點(diǎn)擊的話凶杖,那么history里的當(dāng)前領(lǐng)會(huì)被replace。

<Link>和<NavLink>

NavLinkLink的一個(gè)子類款筑,在Link組件的基礎(chǔ)上增加了繪制組件的樣式智蝠,比如:


<NavLink to="/me" activeStyle={{SomeStyle}} activeClassName="selected">
  My Profile
</NavLink>

使用react router dom實(shí)現(xiàn)你的第一個(gè)demo

現(xiàn)在我們用react router dom來(lái)實(shí)現(xiàn)第一個(gè)demo。

首先奈梳,引入必要的組件杈湾。比如:RouteBrowserRouter

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

接下來(lái)攘须,我們創(chuàng)建一些組件和一些Html標(biāo)簽漆撞。同時(shí)我們用react router v4里的LinkNavLink組件。

const BaseLayout = () => (
  <div className="base">
    <header>
      <p>React Router v4 Browser Example</p>
      <nav>
        <ul>
          <li><Link ="/">Home</Link></li>
          <li><Link ="/about">About</Link></li>
          <li><Link ="/me">Profile</Link></li>
          <li><Link ="/login">Login</Link></li>
          <li><Link ="/register">Register</Link></li>
          <li><Link ="/contact">Contact</Link></li>
        </ul>
      </nav>
    </header>
    <div className="container">
      <Route path="/" exact component={HomePage} />
      <Route path="/about" component={AboutPage} />
      <Route path="/contact" component={ContactPage} />
      <Route path="/login" component={LoginPage} />
      <Route path="/register" component={RegisterPage} />
      <Route path="/me" component={ProfilePage} />
    </div>
    <footer>
      React Router v4 Browser Example (c) 2017
    </footer>
  </div>
);

然后我們來(lái)創(chuàng)建需要的組件:

const HomePage = () => <div>This is a Home Page</div>
const LoginPage = () => <div>This is a Login Page</div>
const RegisterPage = () => <div>This is a Register Page</div>
const ProfilePage = () => <div>This is a Profile Page</div>
const AboutPage = () => <div>This is a About Page</div>
const ContactPage = () => <div>This is a Contact Page</div>

最后,寫App組件叫挟。

const App = () => (
  <BrowserRouter>
    <BaseLayout />
  </BrowserRouter>
)

render(<App />, document.getElementById('root'));

如你所見艰匙,react router v4的組件還非常的易用的限煞。

理解和使用非排他的路由

在上例中抹恳,我們?cè)?code>HomePage組件的路由里使用了屬性exact

<Route path="/" exact component={HomePage} />

這是因?yàn)関4中的路由默認(rèn)都是非排他的署驻,這一點(diǎn)和v3的實(shí)現(xiàn)思路截然不同奋献。如果沒有exact屬性,HomePage組件和其他的組件就會(huì)同事繪制在頁(yè)面上旺上。

如瓶蚂,當(dāng)用戶點(diǎn)了登錄連接以后,"/""/login"都滿足匹配條件宣吱,對(duì)應(yīng)的登錄組件和Home組件就會(huì)同時(shí)出現(xiàn)在界面上窃这。但是,這不是我們期待的結(jié)果征候,所以我們要給"/"path加上exact屬性杭攻。

現(xiàn)在我們來(lái)看看非排他的路由有什么優(yōu)點(diǎn)。假如我們有一個(gè)子菜單組件需要顯示在profile頁(yè)面出現(xiàn)的時(shí)候也出現(xiàn)疤坝。我們可以簡(jiǎn)單的修改BasicLayout來(lái)實(shí)現(xiàn)兆解。

const BaseLayout = () =>  (
  <div className="base">
    <header>
      <p>React Router v4 Browser Example</p>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
          <li>
            <Link to="/me">Profile</Link>
            <Route path="/me" component={ProfileMenu} />
          </li>
          {/*略*/}
        </ul>
      </nav>
    </header>
  </div>
);

這樣我們就會(huì)看到對(duì)應(yīng)于"/me"路徑的組件都繪制出來(lái)了。這就是非排他路由的好處跑揉。

理解排他路由

排他路由是react router v3的默認(rèn)實(shí)現(xiàn)锅睛。只有第一個(gè)匹配的路由對(duì)應(yīng)的組件會(huì)被繪制。這一點(diǎn)也可以用react router v4的Switch組件來(lái)實(shí)現(xiàn)历谍。在Switch組件中现拒,只有第一個(gè)匹配的路由<Route>或者<Redirect>會(huì)被繪制:

import { Switch, Route } from 'react-router';

<Switch>
  <Route exact path="/" component={HomePage} />
  <Route path="/about" component={AboutPage} />
  <Route path="me" component={ProfilePage} />
  <Route component={NotFound} />
</Switch>

瀏覽器歷史

react router v4中,提供了一個(gè)history對(duì)象望侈。這個(gè)對(duì)象包含了多個(gè)api具练,可以用來(lái)操作瀏覽器歷史等。

你也可以在React應(yīng)用里使用history對(duì)象的方法:

history.push("/my-path")
history.replace("/my-path")

用另外的方法可以寫成:

<Link to="/my-path" />
<Redirect to="my-path" />

使用<Redirect>組件實(shí)現(xiàn)重定向

無(wú)論何時(shí)你要重定向到另外一個(gè)地址的時(shí)候甜无,都可以使用Redirect組件:

<Redirect to {{
  pathname: '/register',
  search: '?utm=something',
  state: { referrer: someplage.com }
}}>

或者扛点,更為簡(jiǎn)單的:

<Redirect to="register" />

最后

react router v4讓開發(fā)react應(yīng)用變得更加的簡(jiǎn)單。讓react應(yīng)用內(nèi)的頁(yè)面跳轉(zhuǎn)更加簡(jiǎn)單岂丘。你只需要聲明一個(gè)BrowserRouter或者HashRouter陵究,然后在它的內(nèi)部放上一系列的Route組件,這些主鍵只要包含pathcomponent屬性奥帘。無(wú)論何時(shí)有了匹配的路由铜邮,那么它就會(huì)進(jìn)行非排他的繪制(所有匹配的路由都會(huì)繪制)。你也可以把Route放在Switch組件里來(lái)實(shí)現(xiàn)排他的繪制(只有第一個(gè)匹配的路由會(huì)被繪制)。你可以在路徑中傳遞參數(shù)松蒜,match對(duì)象會(huì)保留這些參數(shù)扔茅。最后,所有在web中使用的路由組件都包含在react-router-dom中秸苗。只需要引入react-router-dom就可以使用召娜。

原文地址:https://www.techiediaries.com/react-router-dom-v4/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市惊楼,隨后出現(xiàn)的幾起案子玖瘸,更是在濱河造成了極大的恐慌,老刑警劉巖檀咙,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雅倒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡弧可,警方通過查閱死者的電腦和手機(jī)蔑匣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)棕诵,“玉大人裁良,你說我怎么就攤上這事∧暝В” “怎么了趴久?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)搔确。 經(jīng)常有香客問我彼棍,道長(zhǎng),這世上最難降的妖魔是什么膳算? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任座硕,我火速辦了婚禮,結(jié)果婚禮上涕蜂,老公的妹妹穿的比我還像新娘华匾。我一直安慰自己,他們只是感情好机隙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布蜘拉。 她就那樣靜靜地躺著,像睡著了一般有鹿。 火紅的嫁衣襯著肌膚如雪旭旭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天葱跋,我揣著相機(jī)與錄音持寄,去河邊找鬼源梭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛稍味,可吹牛的內(nèi)容都是我干的废麻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼模庐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼烛愧!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起赖欣,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤屑彻,失蹤者是張志新(化名)和其女友劉穎验庙,沒想到半個(gè)月后顶吮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粪薛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年悴了,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片违寿。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡湃交,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出藤巢,到底是詐尸還是另有隱情搞莺,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布掂咒,位于F島的核電站才沧,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏绍刮。R本人自食惡果不足惜温圆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望孩革。 院中可真熱鬧岁歉,春花似錦、人聲如沸膝蜈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饱搏。三九已至非剃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窍帝,已是汗流浹背努潘。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人疯坤。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓报慕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親压怠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子眠冈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容