無(wú)廢話快速上手React路由開(kāi)發(fā)
安裝
輸入以下命令進(jìn)行安裝:
// npm npm install react-router-dom // yarn yarn add react-router-dom
react-router相關(guān)標(biāo)簽
react-router
常用的組件有以下八個(gè):
import { BrowserRouter, HashRouter, Route, Redirect, Switch, Link, NavLink, withRouter, } from 'react-router-dom'
簡(jiǎn)單路由跳轉(zhuǎn)
實(shí)現(xiàn)一個(gè)簡(jiǎn)單的一級(jí)路由跳轉(zhuǎn)
import { BrowserRouter as Router, Route, Link } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> <Link to="/home" className="link">跳轉(zhuǎn)Home頁(yè)面</Link> <Link to="/about" className="link">跳轉(zhuǎn)About頁(yè)面</Link> <Route path="/home" component={Home}/> <Route path="/about" component={About}/> </Router> </div> ); } export default App;
效果如下:
要點(diǎn)總結(jié):
Route
組件必須在Router
組件內(nèi)部Link
組件的to
屬性的值為點(diǎn)擊后跳轉(zhuǎn)的路徑Route
組建的path
屬性是與Link
標(biāo)簽的to
屬性匹配的;component
屬性表示Route
組件匹配成功后渲染的組件對(duì)象
嵌套路由跳轉(zhuǎn)
React
的路由匹配層級(jí)是有順序的
例如,在 App
組件中,設(shè)置了兩個(gè)路由組件的匹配路徑,分別是 /home
和 /about
,代碼如下:
import { BrowserRouter as Router, Route, Link, } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> <Link to="/home">跳轉(zhuǎn)Home頁(yè)面</Link> <Link to="/about">跳轉(zhuǎn)About頁(yè)面</Link> <Route path="/home" component={Home}/> <Route path="/about" component={About}/> </Router> </div> ); } export default App;
然后 Home
組件中同樣也想設(shè)置兩個(gè)路由組件的匹配路徑,分別是 /home/one
和 /home/two
,此時(shí)就可以看出,這個(gè) /home/one
和 /home/two
為上一級(jí)路由 /home
的二級(jí)嵌套路由,代碼如下:
import React from 'react' import { Route, Link, } from 'react-router-dom' import One from './one' import Two from './two' function Home () { return ( <> 我是Home頁(yè)面 <Link to="/home/one">跳轉(zhuǎn)到Home/one頁(yè)面</Link> <Link to="/home/two">跳轉(zhuǎn)到Home/two頁(yè)面</Link> <Route path="/home/one" component={One}/> <Route path="/home/two" component={Two}/> </> ) } export default Home
特別注意: Home
組件中的路由組件 One
的二級(jí)路由路徑匹配必須要寫 /home/one
,而不是 /one
,不要以為 One
組件看似在 Home
組件內(nèi)就可以簡(jiǎn)寫成 /one
動(dòng)態(tài)鏈接
NavLink
可以將當(dāng)前處于active
狀態(tài)的鏈接附加一個(gè)active
類名,例如:
import { BrowserRouter as Router, Route, NavLink } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> <NavLink to="/home" className="link">跳轉(zhuǎn)Home頁(yè)面</NavLink> <NavLink to="/about" className="link">跳轉(zhuǎn)About頁(yè)面</NavLink> <Route path="/home" component={Home}/> <Route path="/about" component={About}/> </Router> </div> ); } export default App; /* 設(shè)置active類的樣式 */ .active { font-weight: blod; color: red; }
效果如下:
路由匹配優(yōu)化
當(dāng)點(diǎn)擊跳轉(zhuǎn)鏈接時(shí),會(huì)自動(dòng)去嘗試匹配所有的Route
對(duì)應(yīng)的路徑,如圖所示:
正常情況下,只需匹配到一個(gè)規(guī)則,渲染即可,即匹配成功一個(gè)后,無(wú)需進(jìn)行后續(xù)的匹配嘗試,此時(shí)可以用Switch
組件,如下所示:
import { BrowserRouter as Router, Route, NavLink, Switch, } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> <NavLink to="/home" className="link">跳轉(zhuǎn)Home頁(yè)面</NavLink> <NavLink to="/about" className="link">跳轉(zhuǎn)About頁(yè)面</NavLink> <Switch> <Route path="/home" component={Home}/> <Route path="/about" component={About}/> <Route path="/home" component={Home}/> <Route path="/home" component={Home}/> {/* 此處省略一萬(wàn)個(gè)Route組件 */} <Route path="/home" component={Home}/> </Switch> </Router> </div> ); } export default App;
效果如下:
要點(diǎn)總結(jié):
將多個(gè)Route
組件同時(shí)放在一個(gè)Switch
組件中,即可避免多次無(wú)意義的路由匹配,以此提升性能
重定向
當(dāng)頁(yè)面跳轉(zhuǎn)時(shí),若跳轉(zhuǎn)鏈接沒(méi)有匹配上任何一個(gè) Route
組件,那么就會(huì)顯示 404
頁(yè)面,所以我們需要一個(gè)重定向組件 Redirect
,代碼如下:
import { BrowserRouter as Router, Route, NavLink, Switch, Redirect, } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> <NavLink to="/home" className="link">跳轉(zhuǎn)Home頁(yè)面</NavLink> <NavLink to="/about" className="link">跳轉(zhuǎn)About頁(yè)面</NavLink> <NavLink to="/shop" className="link">跳轉(zhuǎn)Shop頁(yè)面</NavLink> {/* 點(diǎn)擊,跳轉(zhuǎn)到/shop,但該路徑?jīng)]有設(shè)置 */} <Switch> <Route path="/home" component={Home}/> <Route path="/about" component={About}/> <Redirect to="/home" /> {/* 當(dāng)以上Route組件都匹配失敗時(shí),重定向到/home */} </Switch> </Router> </div> ); } export default App;
效果如下:
路由傳參
所有路由傳遞的參數(shù),都會(huì)在跳轉(zhuǎn)路由組件的 props
中獲取到,每種傳參方式接收的方式略有不同
路由傳參的方式一共有三種,依次來(lái)看一下
第一種
第一種是在 Link
組件的跳轉(zhuǎn)路徑上攜帶參數(shù),并在 Route
組件的匹配路徑上通過(guò) :參數(shù)名
的方式接收參數(shù),代碼如下:
import { BrowserRouter as Router, Route, NavLink, Switch, } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> {/* 在 /home 的路徑上攜帶了 張三、18 共兩個(gè)參數(shù) */} <NavLink to="/home/張三/18" className="link">跳轉(zhuǎn)Home頁(yè)面</NavLink> <NavLink to="/about" className="link">跳轉(zhuǎn)About頁(yè)面</NavLink> <Switch> {/* 在 /home 匹配路徑上相同的位置接收了 name、age 兩個(gè)參數(shù) */} <Route path="/home/:name/:age" component={Home}/> <Route path="/about" component={About}/> </Switch> </Router> </div> ); } export default App;
嘗試跳轉(zhuǎn),并打印一下路由組件的 props
可以看到,第一種方式的參數(shù)是通過(guò) props.match.params
來(lái)獲取的
第二種
第二種方式就是通過(guò)在 Link
組件的跳轉(zhuǎn)鏈接后面跟上以 ?
開(kāi)頭,類似 ?a=1&b=3
這樣的參數(shù)進(jìn)行傳遞,代碼如下:
import { BrowserRouter as Router, Route, NavLink, Switch, } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> {/* 在跳轉(zhuǎn)路徑后面以?開(kāi)頭傳遞兩個(gè)參數(shù),分別為name=張三、age=18 */} <NavLink to="/home?name=張三&age=18" className="link">跳轉(zhuǎn)Home頁(yè)面</NavLink> <NavLink to="/about" className="link">跳轉(zhuǎn)About頁(yè)面</NavLink> <Switch> {/* 此處無(wú)需做接收操作 */} <Route path="/home" component={Home}/> <Route path="/about" component={About}/> </Switch> </Router> </div> ); } export default App;
嘗試跳轉(zhuǎn),并打印一下路由組件的 props
可以看到,第二種方式的參數(shù)是通過(guò) props.location.search
來(lái)獲取的,不過(guò)這里的參數(shù)需要自己簡(jiǎn)單做進(jìn)一步轉(zhuǎn)化,這里就不做過(guò)多說(shuō)明了
第三種
第三種方式就是以對(duì)象的形式編寫 Link
組件的 to
跳轉(zhuǎn)屬性,并通過(guò) state
屬性來(lái)傳遞參數(shù),代碼如下:
import { BrowserRouter as Router, Route, NavLink, Switch, } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> {/* 以對(duì)象的形式描述to屬性,路徑屬性名為pathname,參數(shù)屬性名為state */} <NavLink to={{pathname: "/home", state: {name: '張三', age: 18}}} className="link">跳轉(zhuǎn)Home頁(yè)面</NavLink> <NavLink to="/about" className="link">跳轉(zhuǎn)About頁(yè)面</NavLink> <Switch> {/* 此處無(wú)需特地接收屬性 */} <Route path="/home" component={Home}/> <Route path="/about" component={About}/> </Switch> </Router> </div> ); } export default App;
嘗試跳轉(zhuǎn),并打印一下路由組件的 props
可以看到,第三種方式的參數(shù)是通過(guò) props.location.state
來(lái)獲取的
函數(shù)式路由
以上主要都是通過(guò) react-router-dom
中的 Link
組件來(lái)往某個(gè)路由組件跳轉(zhuǎn)
但有時(shí),我們需要更靈活的方式進(jìn)行跳轉(zhuǎn)路由,例如通過(guò)調(diào)用一個(gè)函數(shù),隨時(shí)隨地進(jìn)行路由跳轉(zhuǎn),這就叫函數(shù)式路由
函數(shù)式路由用到的方法有以下 5
個(gè)(下方截圖來(lái)自路由組件的 props
)
5
個(gè)方法分別是 push
、replace
、goForward
、goBack
、go
,接下來(lái)按順序介紹一下這幾個(gè)方法
push
push
方法就是使頁(yè)面跳轉(zhuǎn)到對(duì)應(yīng)路徑,并在瀏覽器中留下記錄(即可以通過(guò)瀏覽器的回退按鈕,返回上一個(gè)頁(yè)面)
舉個(gè)例子:在路由組件 Home
中設(shè)置一個(gè)按鈕 button
,點(diǎn)擊后調(diào)用 push
方法,跳轉(zhuǎn)到 /about
頁(yè)面
import React from 'react' function Home (props) { let pushLink = () => { props.history.push('/about') } return ( <div className="a"> 我是Home頁(yè)面 <button onClick={pushLink}>跳轉(zhuǎn)到about頁(yè)面</button> </div> ) } export default Home
跳轉(zhuǎn)效果如下:
可以看到,通過(guò) push
方法跳轉(zhuǎn)以后,可以通過(guò)瀏覽器的回退按鈕,返回上一個(gè)頁(yè)面
replace
replace
方法與 push
方法類似,不一樣的地方就是,跳轉(zhuǎn)后不會(huì)在瀏覽器中保存上一個(gè)頁(yè)面的記錄(即無(wú)法通過(guò)瀏覽器的回退按鈕,返回上一個(gè)頁(yè)面)
改動(dòng)一下代碼
import React from 'react' function Home (props) { let replaceLink = () => { props.history.replace('/about') } return ( <div className="a"> 我是Home頁(yè)面 <button onClick={replaceLink}>跳轉(zhuǎn)到about頁(yè)面</button> </div> ) } export default Home
跳轉(zhuǎn)效果如下:
可以看到,剛開(kāi)始的路徑是 ‘/' ,然后跳轉(zhuǎn)到 ‘/home' ,再點(diǎn)擊按鈕,通過(guò) replace
方法跳轉(zhuǎn)到 /about
頁(yè)面。最后通過(guò)瀏覽器的回退按鈕返回到了 /
頁(yè)面,說(shuō)明中間的 /home
沒(méi)有被存在瀏覽器的記錄里
goForward
調(diào)用 goForward
方法,就相當(dāng)于點(diǎn)擊了瀏覽器的返回下一個(gè)頁(yè)面按鈕,如下圖所示:
這里就不做過(guò)多演示了
goBack
調(diào)用 goBack
方法,就相當(dāng)于點(diǎn)擊了瀏覽器的返回上一個(gè)頁(yè)面的按鈕,如下圖所示:
go
go
方法顧名思義,是用于跳轉(zhuǎn)到指定路徑的。
該方法接受一個(gè)參數(shù)(參數(shù)類型為 Number
),情況如下:
- 當(dāng)參數(shù)為正數(shù)
n
時(shí),表示跳轉(zhuǎn)到下n
個(gè)頁(yè)面。例如go(1)
相當(dāng)于調(diào)用了一次goForward
方法 - 當(dāng)參數(shù)為負(fù)數(shù)
n
時(shí),表示跳轉(zhuǎn)到上n
個(gè)頁(yè)面。例如go(-3)
相當(dāng)于調(diào)用了三次goBack
方法 - 當(dāng)參數(shù)為
0
時(shí),表示刷新當(dāng)前頁(yè)面
普通組件使用路由
這里區(qū)分兩個(gè)概念,分別為 普通組件 和 路由組件
通過(guò) Route
組件渲染的組件為路由組件 ,其余的基本上都為 普通組件
例如,下方代碼中:Home
組件為路由組件 ; App
組件為普通組件
import { BrowserRouter as Router, Route, NavLink, Switch, } from 'react-router-dom' import Home from './home' export default function App() { return ( <div className="App"> <Router> <NavLink to='/home' className="link">跳轉(zhuǎn)Home頁(yè)面</NavLink> <Switch> <Route path="/home" component={Home}/> </Switch> </Router> </div> ); }
然后,路由組件跟普通組件最大的區(qū)別就是,組件的 props
屬性中是否有下圖所示的內(nèi)容:(前者有,后者無(wú))
此時(shí),react-router-dom
提供了一個(gè) withRouter
方法,可以使普通組件也能像路由組件一樣有那些方法或數(shù)據(jù)可以使用
使用方法如下:
import { BrowserRouter as Router, Route, NavLink, Switch, withRouter, // 1. 引入 witRouter } from 'react-router-dom' import About from './about' function App(props) { console.log(props); // 3. 嘗試打印普通組件App的props,發(fā)現(xiàn)此時(shí)props中已有內(nèi)容了,即普通組件也能擁有跟路由組件一樣類似的功能 return ( <div className="App"> <Router> <NavLink to="/about" className="link">跳轉(zhuǎn)About頁(yè)面</NavLink> <Switch> <Route path="/about" component={About}/> </Switch> </Router> </div> ); } export default withRouter(App); // 2. 通過(guò)withRouter方法對(duì)普通組件做一層包裝處理
補(bǔ)充
replace
在函數(shù)式路由里跳轉(zhuǎn)類型主要有兩種,分別是 push
和 replace
,那么在非函數(shù)式路由中,同樣也可以自定義跳轉(zhuǎn)類型,具體的實(shí)現(xiàn)代碼如下:
import { BrowserRouter as Router, Route, Link } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> <Link to="/home" className="link">跳轉(zhuǎn)Home頁(yè)面</Link> <Link to="/about" className="link">跳轉(zhuǎn)About頁(yè)面</Link> <Route path="/home" component={Home} replace={true}/> {/* replace為true,跳轉(zhuǎn)類型為replace */} <Route path="/about" component={About} replace={false}/> {/* replace為false,跳轉(zhuǎn)類型為push */} </Router> </div> ); } export default App; Route` 組件上有個(gè) `replace` 屬性可以設(shè)定跳轉(zhuǎn)類型,當(dāng)值為 `true` 時(shí),跳轉(zhuǎn)類型為 `replace` ; 為 `false` 時(shí),跳轉(zhuǎn)類型為 `push
excat
路由的匹配默認(rèn)是模糊匹配的,舉個(gè)例子:
import { BrowserRouter as Router, Route, Link, } from 'react-router-dom' import Home from './home' import About from './about' function App() { return ( <div className="App"> <Router> <Link to="/home/abc">跳轉(zhuǎn)Home頁(yè)面</Link> {/* 跳轉(zhuǎn)到/home/abc,但實(shí)際home下沒(méi)有abc這個(gè)路由組件 */} <Link to="/about/abc">跳轉(zhuǎn)About頁(yè)面</Link> {/* 跳轉(zhuǎn)到/about/abc,但實(shí)際home下也沒(méi)有abc這個(gè)路由組件 */} <Route path="/home" component={Home} /> {/* 路由匹配規(guī)則為/home,沒(méi)有設(shè)置exact屬性,當(dāng)前為模糊匹配 */} <Route path="/about" component={About} exact/> {/* 路由匹配規(guī)則為/about,設(shè)置了exact屬性,當(dāng)前為精準(zhǔn)匹配 */} </Router> </div> ); } export default App;
效果如下:
圖中看出,因?yàn)樘D(zhuǎn) /home/abc
時(shí),第一個(gè) Route
組件是模糊匹配的,所以先匹配到了 /home
,因此 Home
組件渲染了 ; 而跳轉(zhuǎn) /about/abc
時(shí),第二個(gè) Route
組件是精準(zhǔn)匹配的,即 /about/abc
不等于 /about
,所以 About
組件也沒(méi)有渲染
總結(jié):
- 如果想要精準(zhǔn)匹配的話,只需要將
Route
組件的exact
屬性設(shè)置為true
即可 - 精準(zhǔn)匹配要謹(jǐn)慎使用,因?yàn)榭赡軙?huì)影響嵌套路由的使用
以上就是無(wú)廢話快速上手React路由的詳細(xì)內(nèi)容,更多關(guān)于React路由快速上手的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
react?fiber使用的關(guān)鍵特性及執(zhí)行階段詳解
這篇文章主要為大家介紹了react?fiber使用的關(guān)鍵特性及執(zhí)行階段詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05React Form組件的實(shí)現(xiàn)封裝雜談
這篇文章主要介紹了React Form組件的實(shí)現(xiàn)封裝雜談,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05使用store來(lái)優(yōu)化React組件的方法
這篇文章主要介紹了使用store來(lái)優(yōu)化React組件的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10nginx配置React靜態(tài)頁(yè)面的方法教程
作為一個(gè)前端開(kāi)發(fā)時(shí)刻想著,怎么把自己寫的東西,丟到自己的服務(wù)器上面,然后展示給別人看。下面我就簡(jiǎn)單直白的寫下,這篇文章主要給大家介紹了關(guān)于nginx配置React靜態(tài)頁(yè)面的方法教程,需要的朋友可以參考下。2017-11-11react中setState的執(zhí)行機(jī)制詳解
setState() 的執(zhí)行機(jī)制包括狀態(tài)合并、批量更新、異步更新、虛擬 DOM 比較和渲染組件等步驟,這樣可以提高性能并優(yōu)化渲染過(guò)程,這篇文章主要介紹了react中的setState的執(zhí)行機(jī)制,需要的朋友可以參考下2023-10-10React中獲取數(shù)據(jù)的3種方法及優(yōu)缺點(diǎn)
這篇文章主要介紹了React中獲取數(shù)據(jù)的3種方法及優(yōu)缺點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02詳解關(guān)于React-Router4.0跳轉(zhuǎn)不置頂解決方案
這篇文章主要介紹了詳解關(guān)于React-Router4.0跳轉(zhuǎn)不置頂解決案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05React-router?v6在Class組件和非組件代碼中的正確使用
這篇文章主要介紹了React-router?v6在Class組件和非組件代碼中的正確使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03