react-router
開始
react-router 是對你前端路由的管理配置.
注意
React項目的可用的路由庫是React-Router
,當然這也是官方支持的。它也分爲:
- react-router 核心組件
- react-router-dom 應用於瀏覽器端的路由庫(單獨使用包含了react-router的核心部分)
- react-router-native 應用於native端的路由
我用的web端路由庫:
{
"react-router-dom": "^5.1.2"
}
具體看官方網站 https://reacttraining.com/react-router/web/guides/quick-start.
安裝
npm install --save react-router-dom
簡單使用
示例:比如一個頁面有導航欄跟內容.
index-router.js
: 主頁面
import React, { Component } from 'react';
import { Link, Router, Switch, Route } from 'react-router-dom';
import About from './About';
import Inbox from './Inbox';
class IndexRouter extends Component {
render() {
return (
<Router>
<h1>app</h1>
<nav>
<ul>
<li><Link to='about'>to About</Link></li>
<li><Link to='inbox'>to Inbox</Link></li>
</ul>
</nav>
<Switch>
<Route path='/about' component={About} />
<Route path='/inbox'>
<Inbox />
</Route>
</Switch>
</Router>
);
}
}
ReactDOM.render(<IndexRouter/>, document.getElementById('root'));
現在我們主頁有一個導航欄,Link標籤是來自react-router-dom
.
這樣形成的效果爲:
這裏用到了 Link, Switch, Router,Route.
react-router-dom組件
Link
替代了<a/>
標籤,而且比其更多的擴展.
屬性to
來指向要跳轉的地方,可以是字符串,可以是對象,可以是一個function.
當是字符串的時,字符串要指向跳轉的地址location,第一個斜槓加不加結果都一樣.
<Link to='about'/>
<!-- or -->
<Link to='/about'/>
當是對象的時候,與字符串的時候有了更多的擴展,對象結構有:
{
pathname: '表示鏈接的地址,跟字符串時一樣',
search: '表示地址query的參數,如 ?sort=name',
hash: '表示地址的hash,如 #about',
state: '保存狀態到該地址 官方:State to persist to the location',
}
示例:
import React from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { Link } from 'react-router-dom';
import About from './About';
export default function App(props) {
const location = {
pathname: 'about',
search: '?to=about',
hash: '#a',
state: {
test: 'value'
}
};
return (
<Router>
<nav>
<Link to={location} >to about</Link>
</nav>
<Switch>
<Route path='/about' component={About} />
</Switch>
</Router>
);
}
效果:
對於state
,關於官方的解釋我也是一知半解,總之它會把該數值傳給About
組件,在props
的location
中存着:
從圖可知,to中的對象都在location裏存着.
Router
The common low-level interface for all router components. Typically apps will use one of the high-level routers instead.
就是說Router只是一個所有router組件的公共接口,要使用則用它的實現類組件:
<BrowserRouter>
<HashRouter>
<MemoryRouter>
<NativeRouter>
<StaticRouter>
這裏我們只講前兩種.
BrowseRouter
就是我們常見的url,history模式.
你可能也注意到了我們之前用得都是這個 Router,它得路徑就是斜槓加路徑完事.
但是它也有幾個參數,
{
basename: '根路徑',
forceRefresh: '是否刷新',
}
import React from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom';
import About from './About';
export default function App() {
return (
<BrowserRouter basename='/browser'>
<nav>
<Link to='/about'>to about</Link>
</nav>
<Route path='/about' component={About} />
</BrowserRouter>
);
}
此時設置的根路徑是:/browser,
HashRouter
這種Router模式是hash模式.不像之前直接後面跟斜槓路徑,而是hash值.
配置項:
{
basename: '根路徑',
hashType: '有三種選擇:slash(default),noslash,hashbang'
}
示例: 默認 hashType
import React from 'react';
import { HashRouter, Link, Route } from 'react-router-dom';
import About from './About';
export default function App() {
return (
<HashRouter basename='/root'>
<nav>
<Link to='/about'>to about</Link>
</nav>
<Route exact path='/about' component={About} />
</HashRouter>
);
}
默認 hashType模式 slash.
示例: noslash
兩種類型區別就在於多了一個斜槓.
Route
The Route component is perhaps the most important component in React Router to understand and learn to use well. Its most basic responsibility is to render some UI when its path
matches the current URL.
必須與Router一起使用,然後會在Router裏去匹配地址,找到Route.
從之前例子中我們可以看出來,Route相當於二級路徑.
props
對於Route的props有:
- match
- location
- history
首先match是有關路徑上的參數:
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import User from './User';
export default function App(props) {
return (
<Router>
<Route path='/user/:username' component={User} />
</Router>
);
}
import React from 'react';
export default function User(props) {
return (
<h2>hello {props.match.params.username}</h2>
);
}
其他信息:
至於history,就是提供了歷史前進後退得函數.
push(path, [state])
- 跳轉到指定路徑replace(path, [state])
- 直接替換路徑go(n)
- 歷史前進幾步goBack()
- 歷史後退幾步goForward()
- 相當於 go(1).
exact屬性
路徑匹配的嚴格程度.
path | location.pathname | exact | matches? |
---|---|---|---|
/one |
/one/two |
true |
no |
/one |
/one/two |
false |
yes |
sensitive屬性
表示是否大小寫敏感.
Switch
Renders the first child <Route>
or <Redirect>
that matches the location.
就是說如果有多個路由匹配一樣,那麼只會渲染第一個route
.
示例:
不用switch:
import React from 'react';
import { Route, BrowserRouter as Router } from 'react-router-dom';
import About from './About';
import Inbox from './Inbox';
export default function App() {
return (
<Router>
<Route path='/about' component={About} />
<Route path='/about' component={Inbox} />
</Router>
);
}
這裏同一個地址,我們有兩個組件,我們沒有用 Switch
結果會是這樣,兩個都顯示:
使用 switch:
import React from 'react';
import { Route, BrowserRouter as Router, Switch } from 'react-router-dom';
import About from './About';
import Inbox from './Inbox';
export default function App() {
return (
<Router>
<Switch>
<Route path='/about' component={About} />
<Route path='/about' component={Inbox} />
</Switch>
</Router>
);
}
結果會是這樣,只會渲染第一個:
Hook 鉤子
react-router-dom 中提供了一些方法.
- useHistory
- useLocation
- useParams
- useRouteMatch
這些可以獲取其對象,其實也可以通過props獲取到.
示例:
import { useHistory } from 'react-router-dom';
const history = useHistory();