npm包的區別
首先從react-router的npm包開始看起,分別有react-router和react-router-dom,兩者的區別在於後者具有一些dom api,比如Link、BrowserRouter、HashRouter。不難發現react-router-dom具有一些在瀏覽器上所需要的api,而react-router只有核心api,所以我們總結下
- react-router 路由核心功能包
- react-router-dom 在瀏覽器上使用的react路由
- react-router-native 在app上使用的react路由
其中react-router-dom和react-router-native都繼承自react-router,所以我們在瀏覽器上開發只需要引入react-router-dom即可
react-router-dom api詳解
我最先接觸的框架是vue,vue中的路由配置使用的是配置檔案,而react使用的是jsx來配置路由,所以初次學習會有點彆扭。
HashRouter和BrowserRouter
其實就是路由的hash和history兩種模式(要是不瞭解這兩種模式之間的區別那就需要去惡補下啦)
並且這兩個元件是路由的容器,必須在最外層
// hash模式
ReactDom.render(
<HashRouter>
<Route path="/" component={Home}/>
</HashRouter>
)
// history模式
ReactDom.render(
<BrowserRouter>
<Route path="/" component={Home}/>
</BrowserRouter>
)
複製程式碼
下面說說HashRouter和BrowserRouter上的引數
- basename 路由的基礎連結,用來部署到非根目錄下,比如你需要將專案部署到 www.xxxx.com/web 下,則設定basename="/web"
- getUserConfirmation 用來攔截Prompt元件,並且決定是否跳轉
- forceRefresh 用來設定是否強制瀏覽器整體重新整理,預設值為false
- keLength 用來設定location.key的長度,預設是6,可以自定義
Prompt
Prompt是用來提示使用者是否要跳轉,給使用者提示資訊預設使用window.confirm,可以結合getUserConfirmation構建自定義提示資訊
<Prompt message={location => {
return '請確認'
}}/>
如果直接返回true,則不會彈窗
複製程式碼
Route
Route是路由的一個原材料,它是控制路徑對應顯示的元件
Route的引數
- path 跳轉的路徑
- component 對應路徑顯示的元件
- render 可以自己寫render函式返回具體的dom,而不需要去設定component
- location 傳遞route物件,和當前的route物件對比,如果匹配則跳轉
- exact 匹配規則,true的時候則精確匹配。
path | url | 是否開啟 | 匹配結果 |
---|---|---|---|
/a | /a/b | false | yes |
/a | /a/b | true | no |
- sensitive 是否區分path的大小寫
path | url | 是否開啟 | 匹配結果 |
---|---|---|---|
/a | /a | true | yes |
/a | /A | true | yes |
- strict 是否匹配後面的/
path | url | 是否開啟 | 匹配結果 |
---|---|---|---|
/a | /a/ | true | yes |
/a | /a/c | true | yes |
/a | /a | true | no |
Router
低階路由,適用於任何路由元件,主要和redux深度整合,使用必須配合history物件
使用Router路由的目的是和狀態管理庫如redux中的history同步對接
<Router history={history}>
...
</Router>
複製程式碼
Link和NavLink
兩者都是跳轉路由,NavLink的引數更多些
Link的api
- to 有兩種寫法,表示跳轉到哪個路由
- 字串寫法
<Link to="/a"/> 複製程式碼
- 物件寫法
<Link to={{ pathname: '/courses', search: '?sort=name', hash: '#the-hash', state: { fromDashboard: true } }}/> 複製程式碼
- 字串寫法
- replace 就是將push改成replace
- innerRef 訪問Link標籤的dom
NavLink的api
- Link的所有api
- activeClassName 路由啟用的時候設定的類名
- activeStyle 路由啟用設定的樣式
- exact 參考Route,符合這個條件才會啟用active類
- strict 參考Route,符合這個條件才會啟用active類
- isActive 接收一個回撥函式,active狀態變化的時候回觸發,返回false則中斷跳轉
const oddEvent = (match, location) => {
console.log(match,location)
if (!match) {
return false
}
console.log(match.id)
return true
}
<NavLink isActive={oddEvent} to="/a/123">元件一</NavLink>
複製程式碼
- location 接收一個location物件,當url滿足這個物件的條件才會跳轉
<NavLink to="/a/123" location={{ key:"mb5wu3", pathname:"/a/123" }}/>
複製程式碼
Redirect
Redirect重定向很簡單,我們直接看程式碼即可
// 基本的重定向
<Redirect to="/somewhere/else" />
// 物件形式
<Redirect
to={{
pathname: "/login",
search: "?utm=your+face",
state: { referrer: currentLocation }
}}
/>
// 採用push生成新的記錄
<Redirect push to="/somewhere/else" />
// 配合Switch元件使用,form表示重定向之前的路徑,如果匹配則重定向,不匹配則不重定向
<Switch>
<Redirect from='/old-path' to='/new-path'/>
<Route path='/new-path' component={Place}/>
</Switch>
複製程式碼
Switch
路由切換,只會匹配第一個路由,可以想象成tab欄
Switch內部只能包含Route、Redirect、Router
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>
</Switch>
複製程式碼
withRouter
當一個非路由元件也想訪問到當前路由的match,location,history物件,那麼withRouter將是一個非常好的選擇,可以理解為將一個元件包裹成路由元件
import { withRouter } from 'react-router-dom'
const MyComponent = (props) => {
const { match, location, history } = this.props
return (
<div>{props.location.pathname}</div>
)
}
const FirstTest = withRouter(MyComponent);
複製程式碼
history物件
用過vue的都知道,vue-router有元件形式的導航,也有程式設計式導航,那react-router怎麼使用api來控制前進後退和重新整理呢?這就需要我們來說明下history物件的作用了
其實在每個路由元件中我們可以使用this.props.history獲取到history物件,也可以使用withRouter包裹元件獲取,
在history中封裝了push,replace,go等方法,具體內容如下
History {
length: number;
action: Action;
location: Location;
push(path: Path, state?: LocationState): void; // 呼叫push前進到一個地址,可以接受一個state物件,就是自定義的路由資料
push(location: LocationDescriptorObject): void; // 接受一個location的描述物件
replace(path: Path, state?: LocationState): void; // 用頁面替換當前的路徑,不可再goBack
replace(location: LocationDescriptorObject): void; // 同上
go(n: number): void; // 往前走多少也頁面
goBack(): void; // 返回一個頁面
goForward(): void; // 前進一個頁面
block(prompt?: boolean | string | TransitionPromptHook): UnregisterCallback;
listen(listener: LocationListener): UnregisterCallback;
createHref(location: LocationDescriptorObject): Href;
}
複製程式碼
這樣我們想使用api來操作前進後退就可以呼叫history中的方法啦