React專題6: 路由React Router

1. 后端路由與前端路由

多頁(yè)面應(yīng)用和后端路由
在傳統(tǒng)的Web應(yīng)用中,瀏覽器根據(jù)地址欄的URL向服務(wù)器發(fā)送一個(gè)HTTP請(qǐng)求,服務(wù)器根據(jù)URL返回一個(gè)HTML頁(yè)面。這種情況下黔寇,一個(gè)URL對(duì)應(yīng)一個(gè)HTML頁(yè)面,一個(gè)Web應(yīng)用包含很多HTML頁(yè)面斩萌,這樣的應(yīng)用就是 多頁(yè)面應(yīng)用缝裤;在多頁(yè)面應(yīng)用中屏轰,頁(yè)面路由的控制由服務(wù)器端負(fù)責(zé),這種路由方式稱為 后端路由憋飞。

單頁(yè)面應(yīng)用和前端路由
URL的變化可以引起頁(yè)面內(nèi)容的變化霎苗,但不會(huì)向服務(wù)器發(fā)送新的請(qǐng)求,頁(yè)面的內(nèi)容也會(huì)發(fā)生變化,但這只是邏輯上的頁(yè)面變化榛做,無(wú)論URL如何變化唁盏,對(duì)應(yīng)的HTML文件都是同一個(gè),這樣叫做 單頁(yè)面應(yīng)用. 在單頁(yè)面應(yīng)用中,URL發(fā)生變化并不會(huì)向服務(wù)器發(fā)送新的請(qǐng)求检眯,所以“邏輯頁(yè)面”(這個(gè)名稱用來(lái)和真實(shí)的HTML頁(yè)面區(qū)分)的路由只能由前端負(fù)責(zé)厘擂,這種路由方式稱為 前端路由

React Router就是一種前端路由的實(shí)現(xiàn)方式轰传。通過(guò)使用React Router可以讓W(xué)eb應(yīng)用根據(jù)不同的URL渲染不同的組件,這樣的組件渲染方式可以解決更加復(fù)雜的業(yè)務(wù)場(chǎng)景瘪撇。例如获茬,當(dāng)URL的pathname為/list時(shí),頁(yè)面會(huì)渲染一個(gè)列表組件倔既,當(dāng)點(diǎn)擊列表中的一項(xiàng)時(shí)恕曲,pathname更改為/item/:id(id為參數(shù)),舊的列表組件會(huì)被卸載渤涌,取而代之的是一個(gè)新的單一項(xiàng)的詳情組件佩谣。

2. 安裝路由

npm install react-router-dom

React Router包含3個(gè)庫(kù):react-router、react-router-dom和react-router-native实蓬。
react-router提供最基本的路由功能茸俭,實(shí)際使用時(shí),我們不會(huì)直接安裝react-router.
而是根據(jù)應(yīng)用運(yùn)行的環(huán)境選擇安裝react-router-dom(在瀏覽器中使用)或react-router-native(在react-native中使用)安皱。
react-router-dom和react-router-native都依賴于react-router调鬓,所以在安裝時(shí),react-router也會(huì)自動(dòng)安裝酌伊。
所以我們只需要安裝 react-router-dom

3. 引入路由

引入路由

// 哈希模式
import {HashRouter as Router, Link, Route} from 'react-router-dom'

//或者

// history模式
import {BrowserRouter as Router, Link, Route} from 'react-router-dom'

// ReactRouter三大組件
// Router 所有路由組件的根組件, 包裹路由規(guī)則的最外層容器
// Route 路由規(guī)則匹配組件, 顯示當(dāng)前規(guī)則對(duì)應(yīng)的組件
// Link  路由跳轉(zhuǎn)組件

4. HashRouter和BrowserRouter

Router可以理解成路由器腾窝,一個(gè)應(yīng)用中只需要一個(gè)Router實(shí)例, React Router中的其他組件必須作為Router組件的后代組件使用。但Router中只能有唯一的一個(gè)子元素
Router會(huì)創(chuàng)建一個(gè)history對(duì)象居砖,history用來(lái)跟蹤URL虹脯,當(dāng)URL發(fā)生變化時(shí),Router的后代組件會(huì)重新渲染奏候。React Router中提供的其他組件可以通過(guò)context獲取history對(duì)象

BrowserRouter使用HTML 5的history API(pushState循集、replaceState等)實(shí)現(xiàn)應(yīng)用的UI和URL的同步
BrowserRouter創(chuàng)建的URL形式如下:http://example.com/some/path
使用BrowserRouter時(shí),一般還需要對(duì)服務(wù)器進(jìn)行配置蔗草,讓服務(wù)器能正確地處理所有可能的URL暇榴。例如厚棵,當(dāng)瀏覽器發(fā)送http://example.com/some/pathhttp://example.com/some/path2兩個(gè)請(qǐng)求時(shí),服務(wù)器需要能返回正確的HTML頁(yè)面(也就是單頁(yè)面應(yīng)用中唯一的HTML頁(yè)面)

HashRouter使用URL的hash實(shí)現(xiàn)應(yīng)用的UI和URL的同步蔼紧。
HashRouter創(chuàng)建的URL形式如下:http://example.com/#/some/path
使用HashRouter則不存在這個(gè)問(wèn)題婆硬,因?yàn)閔ash部分的內(nèi)容會(huì)被服務(wù)器自動(dòng)忽略荧关,真正有效的信息是hash前面的部分叁温,而對(duì)于單頁(yè)面應(yīng)用來(lái)說(shuō)鲜结,這部分內(nèi)容是固定的

5. Route

Route是匹配組件, 常用的屬性有path和component.

Route的exact和strict修飾符

exact 精確匹配 默認(rèn)為false遇汞,如果為true時(shí)熊楼,需要和路由相同時(shí)才能匹配通惫。
false 路由:'/Home' url '/Home' 和 '/Home/myPage' 都會(huì)匹配
true 路由:'/Home' 只有url '/Home'才匹配, url '/Home/myPage' 不匹配

strict 斜杠敏感 默認(rèn)為false叉瘩,如果為true時(shí)教硫,url對(duì)斜杠敏感
false url '/Home' 和 url '/Home/' 視為相同的url
true url '/Home' 和 url '/Home/' 視為不相同的url

6. Link

Link是跳轉(zhuǎn)組件, 常用的屬性是 to
to屬性值可是字符串
也可以是對(duì)象: 這個(gè)對(duì)象包含 pathname逻卖、search宋列、hash、state四個(gè)屬性
例如:

let toArgs = {
    // 跳轉(zhuǎn)的路徑
    pathname: '/User',
    // get的入?yún)?    search: '?user=admin',
    // hash的值
    hash: '#abc',
    // 組件的值
    state: {fromHome: true}
}

組件中的 this.props.location 存放著這個(gè)入?yún)?br> 在組件中查看這個(gè)入?yún)?
this.props.location.state.fromHome;

7. switch

當(dāng) Router中的Route有多個(gè)符合匹配條件時(shí), 如果不添加switch, 所有匹配的組件都會(huì)渲染
當(dāng) 這些Route被 switch包裹時(shí), 當(dāng)?shù)谝粋€(gè)符合匹配條件的組件渲染后, 不再向下匹配. (保證只顯示第一個(gè)匹配的組件)

8. history

路由頁(yè)面跳轉(zhuǎn)
history.push(path,[state])
history.replace(path,[state])
區(qū)別:
push是把新頁(yè)面放入棧中, 保留上一個(gè)頁(yè)面的歷史記錄, 這樣返回還可以回到上一個(gè)頁(yè)面
replace是把新頁(yè)面替換上一個(gè)頁(yè)面在棧中的歷史記錄, 這樣返回的時(shí)候會(huì)回到上上個(gè)頁(yè)面
現(xiàn)在有三個(gè)頁(yè)面 a->b->c
b跳轉(zhuǎn)c的時(shí)候, 如果使用push到c頁(yè)面,在c頁(yè)面點(diǎn)擊返回回到b頁(yè)面
b跳轉(zhuǎn)c的時(shí)候, 如果使用replace到c頁(yè)面,在c頁(yè)面點(diǎn)擊返回回到a頁(yè)面

// 向前或向后跳轉(zhuǎn)n個(gè)頁(yè)面, 正數(shù)為前進(jìn), 負(fù)數(shù)為后退
this.props.history.go(n)

// 前進(jìn)
this.props.history.go(1);
//或者
this.props.history.goForward();

// 回退
 this.props.history.go(-1);
//或者
this.props.history.goBack();

9. 動(dòng)態(tài)路由

Route這樣寫(xiě) /path/:動(dòng)態(tài)參數(shù) 如:
<Route path='/User/:user' component={User}></Route>
Link這樣寫(xiě) /path/具體的參數(shù) 如:
<Link className='linkC' to='/User/admin'>用戶</Link>
生產(chǎn)的url是 #/User/admin
組件的this.props.match.params 存放這個(gè)動(dòng)態(tài)參數(shù)
在組件中查看這個(gè)動(dòng)態(tài)參數(shù)
this.props.match.params.user;

10. Redirect重定向

待補(bǔ)充...

11. 組件被加入路由后, 組件的this.props新增屬性

this.props.history

this.props.history提供了push, replace, go, goBack, goForward等方法

// this.props.history.go(n)
// 向前或向后跳轉(zhuǎn)n個(gè)頁(yè)面, 正數(shù)為前進(jìn), 負(fù)數(shù)為后退

// 前進(jìn)
this.props.history.go(1);
this.props.history.goForward();

// 回退
this.props.history.go(-1);
this.props.history.goBack();

this.props.location

this.props.location存放的是Link to屬性傳入的對(duì)象,包括pathname评也、search炼杖、hash、state四個(gè)屬性

let toArgs = {
    // 跳轉(zhuǎn)的路徑
    pathname: '/User',
    // get的入?yún)?    search: '?user=admin',
    // hash的值
    hash: '#abc',
    // 組件的值
    state: {fromHome: true}
}
<Link className='linkC' to={toArgs}>登錄</Link>
// 組件中的 this.props.location 存放著這個(gè)入?yún)?// 在組件中查看這個(gè)入?yún)?this.props.location.state.fromHome;

this.props.match

this.props.match.params存放著動(dòng)態(tài)路由的動(dòng)態(tài)參數(shù)

// Route這樣寫(xiě) /path/:動(dòng)態(tài)參數(shù) 如:
<Route path='/User/:user' component={User}></Route>
// Link這樣寫(xiě) /path/具體的參數(shù) 如:
<Link className='linkC' to='/User/admin'>用戶</Link>
// 訪問(wèn)這個(gè)屬性: 
this.props.match.params.user;

11. window.location

頁(yè)面刷新時(shí), 如果想要訪問(wèn)到當(dāng)前頁(yè)面的哈希路徑, 以此來(lái)作為判斷條件做一些預(yù)處理, 在react的生命周期函數(shù)UNSAFE_componentWillMount執(zhí)行時(shí), props屬性還沒(méi)有被注入數(shù)據(jù)的情況, 可以通過(guò)window.location來(lái)訪問(wèn)到hash路徑

UNSAFE_componentWillMount(){
    /* 每次刷新頁(yè)面時(shí),可以通過(guò)window.location獲取到當(dāng)前的hash路徑, 以此來(lái)獲取一下當(dāng)前頁(yè)等信息. 
    然后定位對(duì)應(yīng)的位置等操作. 因?yàn)轫?yè)面剛刷新, 在willMount的時(shí)候我們還無(wú)法訪問(wèn)props.
    */
    console.log('頁(yè)面刷新時(shí)會(huì)調(diào)用這個(gè)方法. 來(lái)查看一下刷新時(shí)的hash路由');
    //可以看到這時(shí)候props還沒(méi)有數(shù)據(jù), 如果想拿到哈希路徑, 就需要訪問(wèn)window.location
    console.log('this.props',this.props); 
    console.log(window.location.hash);
    console.log(window.location.hash.split('/'));
    console.log(window.location.hash.split('/')[1]);
  }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盗迟,一起剝皮案震驚了整個(gè)濱河市坤邪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罚缕,老刑警劉巖艇纺,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異邮弹,居然都是意外死亡黔衡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門腌乡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)员帮,“玉大人,你說(shuō)我怎么就攤上這事导饲±谈撸” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵渣锦,是天一觀的道長(zhǎng)硝岗。 經(jīng)常有香客問(wèn)我,道長(zhǎng)袋毙,這世上最難降的妖魔是什么型檀? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮听盖,結(jié)果婚禮上胀溺,老公的妹妹穿的比我還像新娘裂七。我一直安慰自己,他們只是感情好仓坞,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布背零。 她就那樣靜靜地躺著,像睡著了一般无埃。 火紅的嫁衣襯著肌膚如雪徙瓶。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天嫉称,我揣著相機(jī)與錄音侦镇,去河邊找鬼。 笑死织阅,一個(gè)胖子當(dāng)著我的面吹牛壳繁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荔棉,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闹炉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了江耀?” 一聲冷哼從身側(cè)響起剩胁,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤诉植,失蹤者是張志新(化名)和其女友劉穎祥国,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體晾腔,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舌稀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了灼擂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壁查。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖剔应,靈堂內(nèi)的尸體忽然破棺而出睡腿,到底是詐尸還是另有隱情,我是刑警寧澤峻贮,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布席怪,位于F島的核電站,受9級(jí)特大地震影響纤控,放射性物質(zhì)發(fā)生泄漏挂捻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一船万、第九天 我趴在偏房一處隱蔽的房頂上張望刻撒。 院中可真熱鬧骨田,春花似錦、人聲如沸声怔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捧搞。三九已至抵卫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胎撇,已是汗流浹背介粘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晚树,地道東北人姻采。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像爵憎,于是被迫代替她去往敵國(guó)和親慨亲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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