新手理解react-router關(guān)鍵點(diǎn)解析

1 為什么需要使用react-router

當(dāng)你寫了很多react組件后,想要實(shí)現(xiàn)不同組件之間的切換和跳轉(zhuǎn)的時(shí)候,react-router就派上用場(chǎng)了概作。

2 使用react-router-dom還是react-router

兩者區(qū)別不大,一般只使用react-router-dom就能滿足我們的需要枣抱。

3 安裝方法

npm install --save react-router-dom

4 如何使用

使用前要先引入

import { BrowserRouter as Router, Route, Link } from 'react-router-dom'//這里將BrowserRouter重命名為Router

使用舉例


先打開(kāi)本地服務(wù)器布疙,如果不懂怎么做蚊惯,請(qǐng)看我的另一篇文章http://www.reibang.com/p/d08db717a66f

<Router>
  <div>
    <ul>
      <li><Link to="/">主頁(yè)</Link></li>
      <li><Link to="/hot">熱門</Link></li>
      <li><Link to="/zhuanlan">專欄</Link></li>
    </ul>
    <hr/>
    <Route  exact path="/" component={App}></Route>
    <Route path="/hot" component={Hot} ></Route>
    <Route path="/zhuanlan" component={Zhuanlan}></Route>
  </div>
</Router>

<Router></Router>相當(dāng)于一個(gè)盒子,里面只能包含一個(gè)子元素灵临。

react-router4之后截型,<Router></Router>標(biāo)簽里面可以包含任何html標(biāo)簽和react組件。

然而并不是react-route的其他標(biāo)簽必須包在Router里面儒溉,比如只要通過(guò)import { Route, Link} from 'react-route-dom'引入宦焦,可以隨意單獨(dú)使用Route和Link標(biāo)簽。

<Link></Link>標(biāo)簽和<a></a>標(biāo)簽類似顿涣,點(diǎn)擊<Link></Link>標(biāo)簽中的元素可以實(shí)現(xiàn)組件跳轉(zhuǎn)波闹。跳轉(zhuǎn)到哪個(gè)組件要看path的值"/"代表根路徑,相當(dāng)于localhost:8080這個(gè)路徑园骆,我們發(fā)現(xiàn)有一個(gè)<Route></Route>的path屬性和這個(gè)Link標(biāo)簽的path值相同舔痪,當(dāng)用戶點(diǎn)擊Link標(biāo)簽時(shí),會(huì)觸發(fā)和它具有相同path值的Route的component渲染锌唾,并且瀏覽器的網(wǎng)址那里的url變成他們的path值代表的路徑锄码。

因此,我們可以理解晌涕,“路由”就是要實(shí)現(xiàn)url跳轉(zhuǎn)滋捶,注意不要和直接打開(kāi)html文件哪個(gè)本地文件路徑搞混了,這里改變的是網(wǎng)址URL余黎,就是你的path值重窟,前面加上localhost:8080。

那么問(wèn)題來(lái)了惧财,url和文件路徑的區(qū)別是什么巡扇?

我們以前練習(xí)的時(shí)候,打開(kāi)我們的index.html是手動(dòng)直接打開(kāi)的垮衷,它在瀏覽器中顯示的路徑就是以我們的電腦哪個(gè)磁盤開(kāi)始的資源路徑厅翔,就是這個(gè)文件在電腦中的位置。

url路徑不同于資源路徑搀突,我們的組件Hot的url路徑是localhost:8080/hot刀闷,這是我們自己定義的,和Hot組件在電腦中的位置無(wú)關(guān),反正只要我們?cè)?lt;Route></Route>中定義了這個(gè)component的path甸昏,那么這個(gè)組件的url就確定了顽分,不用管它在電腦中的位置,當(dāng)然施蜜,在當(dāng)前文件中必須先引入這個(gè)組件卒蘸,還是按電腦中的相對(duì)路徑來(lái)的。所以花墩,你理解資源路徑和url的區(qū)別了嗎婚夫?

5 history的理解

如果你用過(guò)老版本的react-router仲锄,你一定知道history蛀骇。history是用來(lái)兼容不同瀏覽器或者環(huán)境下的歷史記錄管理的评汰,當(dāng)我跳轉(zhuǎn)或者點(diǎn)擊瀏覽器的后退按鈕時(shí),history就必須記錄這些變化祠肥。

browserHistory h5的history兼容性不好武氓,需要后端支持,在渲染組件的時(shí)候轉(zhuǎn)成hashHistory仇箱。

<Router history={browserHistory} routes={routes} />,
這種情況需要對(duì)服務(wù)器改造县恕。否則用戶直接向服務(wù)器請(qǐng)求某個(gè)子路由,會(huì)顯示網(wǎng)頁(yè)找不到的404錯(cuò)誤剂桥。

browserHistory 模式下忠烛,URL 是指向真實(shí) URL 的資源路徑,當(dāng)通過(guò)真實(shí) URL 訪問(wèn)網(wǎng)站的時(shí)候(首頁(yè))权逗,這個(gè)時(shí)候可以正常加載我們的網(wǎng)站資源美尸,而用戶在非首頁(yè)下手動(dòng)刷新網(wǎng)頁(yè)時(shí),由于路徑是指向服務(wù)器的真實(shí)路徑斟薇,但該路徑下并沒(méi)有相關(guān)資源(因?yàn)閡rl路徑是path中設(shè)置的路徑师坎,并不是資源路徑),用戶訪問(wèn)的資源不存在堪滨,返回給用戶的是 404 錯(cuò)誤

官方推薦使用browserHistory

History API 提供了 pushState() 和 replaceState() 方法來(lái)增加或替換歷史記錄胯陋。

而 hash 沒(méi)有相應(yīng)的方法,所以并沒(méi)有替換歷史記錄的功能袱箱。但 react-router 通過(guò) polyfill 實(shí)現(xiàn)了此功能遏乔,具體實(shí)現(xiàn)沒(méi)有看,好像是使用 sessionStorage发笔。

另一個(gè)原因是 hash 部分并不會(huì)被瀏覽器發(fā)送到服務(wù)端按灶,也就是說(shuō)不管是請(qǐng)求

http://domain.com/index.html#foo 還是http://domain.com/index.html#bar ,服務(wù)只知道請(qǐng)求了 index.html 并不知道 hash 部分的細(xì)節(jié)筐咧。而 History API 需要服務(wù)端支持,這樣服務(wù)端能獲取請(qǐng)求細(xì)節(jié)。

還有一個(gè)原因是因?yàn)橛行?yīng)用會(huì)忽略 URL 中的 hash 部分量蕊。

對(duì)于初學(xué)者铺罢,我推薦先使用<Router history={hashHistory}>,并且在引入Router時(shí)使用HashHistory as Router代替BrowserHistory as Router,以免出現(xiàn)不必要的麻煩残炮。

6 react-router4路由嵌套

什么是路由嵌套

路由嵌套势就,顧名思義就是路由/URL路徑的嵌套苞冯,比如舅锄,若Hot組件的路由是localhost:8080/hot皇忿,如果我們想要得Hot組件添加一個(gè)子組件Girl鳍烁,每次我們渲染Girl的時(shí)候,Hot也會(huì)自動(dòng)和他一起渲染糊闽,那么可以這樣寫

//父組件中
<Router>
  <div>
    <Route  exact path="/" component={App}></Route>
    <Route path="/hot" component={Hot} ></Route>
    <Route path="/zhuanlan" component={Zhuanlan}></Route>
  </div>
</Router>

//子組件中
    <Route path="/hot/girl" component={Girl} ></Route>  

理解<Route></Route>

在react-router4中墓怀,將他看做一個(gè)類似于組件的東西傀履,你想在哪里渲染組件钓账,就把他寫在哪里

//入口組件app.js
            <Router history={hashHistory}>
                <div>
                    <Route exact path="/" component={PCIndex}></Route>              
                    <Route path="/hf" component={HeaderAndFooter}></Route>
                </div>  
            </Router>

//HeaderAndFooter組件
            <div>
                <PCHeader />
                <Route path="/hf/paper" component={BodyPaper}></Route>
                <Route path="/hf/people" component={BodyPeople}></Route>
                <BodyFooter />
            </div>

路由對(duì)應(yīng):

localhost:8080----渲染PCIndex組件

localhost:8080/hf----渲染HeaderAndFooter組件

localhost:8080/hf/paper----同時(shí)渲染BodyPaper和HeaderAndFooter組件組件,并且BodyPaper組件在PCHeader組件和BodyFooter組件的中間

localhost:8080/hf/people----同時(shí)渲染BodyPeople和HeaderAndFooter組件組件啦粹,并且BodyPeople組件在PCHeader組件和BodyFooter組件的中間

7 組件路由參數(shù)傳遞match和:id的理解

match參數(shù)的理解

通過(guò)Route路由的組件唠椭,可以拿到一個(gè)match參數(shù)贪嫂,這個(gè)參數(shù)是一個(gè)對(duì)象力崇,其中包含幾個(gè)數(shù)據(jù):

isExact:這個(gè)關(guān)鍵字表示是為作全等匹配亮靴,比如台猴,寫了exact饱狂,“/”只能匹配PCIndex組件休讳,而不寫那就問(wèn)題大了俊柔,在localhost:8080路徑下雏婶,還可以匹配到HeaderAndFooter組件留晚,并將其渲染。

params:path中包含的一些額外數(shù)據(jù)

path:Route組件path屬性的值

url:實(shí)際url的hash值

示例

const HeaderAndFooter = ({match}) => (//{match}要先引入
    <div>
        <PCHeader />
        <Route path={`${match.url}/paper`} component={BodyPaper}></Route>
        <Route path="/hf/people" component={BodyPeople}></Route>
        <BodyFooter />
    </div>
)

export default HeaderAndFooter;

${match.url}獲取到的路徑就是HeaderAndFooter的path路徑

這里用到了es6的模板字符串功能,兩個(gè)反單引號(hào)括起來(lái)的字符串参歹,里面可以放js語(yǔ)句犬庇,比如變量械筛,但需要將變量名寫在${}之中

模板字符串之中還能調(diào)用函數(shù)let msg = Hello, ${place};

:id的理解

:id其實(shí)是官網(wǎng)文檔中的一種寫法,你也可以任意寫這個(gè)參數(shù),它放在url中赤赊,也是用來(lái)傳遞參數(shù)的抛计。它不是要參與url路由吹截,react-router會(huì)通過(guò)props.params傳遞給組件波俄,id表示參數(shù)變量懦铺,id有實(shí)際值將替換掉 :id ,變?yōu)閷?shí)際參數(shù)冬念。

比如:

當(dāng)我們請(qǐng)求/home/123/app/456的時(shí)候急前, 路由就會(huì)匹配到/home/:userId/app/:appId

其中params就是指的上面的userId 和 appId

轉(zhuǎn)換成json就是{userId: 123, appId: 456}

利用這種參數(shù)傳值:

示例

<Route path="/hf/people" component={BodyPeople}></Route>
<Route path={`${match.url}/:id`} component={BodyPaper}></Route>

當(dāng)我們?cè)L問(wèn)localhost:8080/fh/people的時(shí)候,就會(huì)渲染BodyPeople組件据块,people也會(huì)替換了url中的:id另假,渲染BodyPaper組件边篮。

可以用Switch解決這個(gè)問(wèn)題凌受,Switch下每次只匹配一個(gè)路由思杯,并且將這種含參數(shù)的url往下寫也是一個(gè)很好的習(xí)慣誊册。

 <Switch>
    {/* 用了Switch 這里每次只匹配一個(gè)路由案怯,所有只有一個(gè)節(jié)點(diǎn)。 */}
    <Route path="/about" component={About}/>
    <Route path="/:user" component={User}/>
    <Route component={NoMatch}/>
  </Switch>

綜合示例

  //父組件中
    const Hot=({match})=>(<div>
    
    <h2>熱門</h2>
    <Link to={`${match.url}/article`}>文章</Link>
    <Link to={`${match.url}/qa`}>問(wèn)答</Link>
    <Link to={`${match.url}/news`}>新聞</Link>
    <hr/>
    <Route path={`${match.url}/:type`} component={Content}></Route>
    
    </div>)
    //子組件中
    const Content=({match})=>(
    <div>
      <h2>熱門子目錄</h2>
      <p>{match.params.type}</p>
    </div>
)

可以發(fā)現(xiàn)match.params.type輕松取到了url中的參數(shù)至会。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宵蛀,一起剝皮案震驚了整個(gè)濱河市术陶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌塘匣,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笤闯,死亡現(xiàn)場(chǎng)離奇詭異颗味,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)捐韩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門屎债,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人躯喇,你說(shuō)我怎么就攤上這事≌梗” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵栖博,是天一觀的道長(zhǎng)侨把。 經(jīng)常有香客問(wèn)我,道長(zhǎng)省店,這世上最難降的妖魔是什么芦劣? 我笑而不...
    開(kāi)封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任寸认,我火速辦了婚禮,結(jié)果婚禮上串慰,老公的妹妹穿的比我還像新娘偏塞。我一直安慰自己,他們只是感情好邦鲫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布灸叼。 她就那樣靜靜地躺著,像睡著了一般庆捺。 火紅的嫁衣襯著肌膚如雪古今。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天疼燥,我揣著相機(jī)與錄音沧卢,去河邊找鬼。 笑死醉者,一個(gè)胖子當(dāng)著我的面吹牛但狭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播撬即,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼立磁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了剥槐?” 一聲冷哼從身側(cè)響起唱歧,我...
    開(kāi)封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后颅崩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體几于,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年沿后,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沿彭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尖滚,死狀恐怖喉刘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情漆弄,我是刑警寧澤睦裳,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站撼唾,受9級(jí)特大地震影響廉邑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜倒谷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一鬓催、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恨锚,春花似錦、人聲如沸倍靡。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)塌西。三九已至他挎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捡需,已是汗流浹背办桨。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留站辉,地道東北人呢撞。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像饰剥,于是被迫代替她去往敵國(guó)和親殊霞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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

  • Lesson11汰蓉、首先確保安裝了Node.js和npm依賴包管理工具2绷蹲、在git上克隆官方示例程序 git clo...
    冰_心閱讀 2,709評(píng)論 0 16
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器祝钢,智...
    卡卡羅2017閱讀 134,659評(píng)論 18 139
  • React-Router v4 1. 設(shè)計(jì)理念1.1. 動(dòng)態(tài)路由1.2. 嵌套路由1.3. 響應(yīng)式路由 2. 快速...
    wlszouc閱讀 8,556評(píng)論 0 14
  • 感謝相遇—有我愛(ài)你 愿角色對(duì)調(diào)比规,換你愛(ài)我愛(ài)到瘋掉 你可以一直守護(hù)著張瑤,但也請(qǐng)讓我一直守護(hù)著你——張浩杰 2...
    青澀劉哈哈閱讀 1,132評(píng)論 3 5
  • 在那甜瓜成熟的季節(jié)一百五十一拦英,掃描二維碼了解小說(shuō)更多細(xì)節(jié):劉曉安被通知馬上回大學(xué)的事情蜒什,自己只是給李老師說(shuō)了一下,...
    思想聚焦的原創(chuàng)閱讀 177評(píng)論 0 5