了解
- React的一個插件庫
- 專門用來實作一個SPA應用
- 基于React的項目都會使用到此庫
React-router-web相關的API
< Link >
- 在React中靠酷遊連結去切換元件
//案例
import { Link } from 'react-router-dom'
//路由跳轉連結
<Link to="/about">About</Link>
< BrowserRouter >
import { BrowserRouter } from 'react-router-dom'
//把APP内的路由元件都交給一個路由管理
<BrowserRouter>
<App/>
</BrowserRouter>
< Route >
import { Route } from 'react-router-dom'
<Route path="/home" component={Home}/>
<Route path="/user/:username" component={User}/>
const User = ({ match }) => {
return <h1>Hello {match.params.username}!</h1>
}
< NavLink>
- 一個特殊版本的 Link,當它與目前 URL 比對時,為其渲染元素添加樣式屬性
import { NavLink } from 'react-router-dom'
// 實作導航連結高亮展示,顯示預設顔色
<NavLink to="/about">About</NavLink>
//自定義選中樣式
<NavLink
to="/about"
activeClassName="selected"
>About</NavLink>
//内聯方式自定義選中樣式
<NavLink
to="/about"
activeStyle={{
fontWeight: 'bold',
color: 'red'
}}
>About</NavLink>
//在樣式中設定選中樣式
.selected{
background-color:xxx !importent; //必須添加!importent 提高樣式權限
color:xxx !importent;
}
< Switch>
- 渲染與該位址比對的第一個子節點 或者
- 多個路由的話使用
import { Switch, Route } from 'react-router'
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/user" component={User}/>//比對到第一個user路由元件,顯示該元件
<Route path="/user" component={test}/>//不顯示該元件
</Switch>
< Redirect >
- 渲染 将使導航到一個新的位址。這個新的位址會覆寫 history 棧中的目前位址
- 一般寫在路由的最下方,當所有路由無法比對時,跳轉到Redirect指定的路由
嵌套路由

嵌套路由代碼案例
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
// 路由元件
const Main = () => <h2>Main</h2>;
const Sandwiches = () => <h2>Sandwiches</h2>;
const Tacos = ({ routes }) => (
<div>
<h2>Tacos</h2>
<ul>
<li>
<Link to="/tacos/bus">Bus</Link>
</li>
<li>
<Link to="/tacos/cart">Cart</Link>
</li>
</ul>
{routes.map((route, i) => <RouteWithSubRoutes key={i} {...route} />)}
</div>
);
const Bus = () => <h3>Bus</h3>;
const Cart = () => <h3>Cart</h3>;
// 路由配置
const routes = [
{
path: "/sandwiches",
component: Sandwiches
},
{
path: "/tacos",
component: Tacos,
routes: [
{
path: "/tacos/bus",
component: Bus
},
{
path: "/tacos/cart",
component: Cart
}
]
}
];
//對路由元件容器的二次封裝
const RouteWithSubRoutes = route => (
<Route
path={route.path}
render={props => (
<route.component {...props} routes={route.routes} />
)}
/>
);
const RouteConfigExample = () => (
<Router>
<div>
<ul>
<li>
<Link to="/tacos">Tacos</Link>
</li>
<li>
<Link to="/sandwiches">Sandwiches</Link>
</li>
</ul>
{routes.map((route, i) => <RouteWithSubRoutes key={i} {...route} />)}
</div>
</Router>
);
export default RouteConfigExample;
路由傳參
向路由元件傳遞params參數
- 路由連結(攜帶參數):< link to="/demo/tom/18"></ link >
- 注冊路由(接收參數):< Route path="/demo/:name/:age" component={Test}></ Route >
- 接收參數:const {name ,age} = this.props.match.params
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
const ParamsExample = () => (
<Router>
<div>
<h2>Accounts</h2>
<ul>
<li>
<Link to="/netflix">Netflix</Link>
</li>
<li>
<Link to="/zillow-group">Zillow Group</Link>
</li>
<li>
<Link to="/yahoo">Yahoo</Link>
</li>
<li>
<Link to="/modus-create">Modus Create</Link>
</li>
</ul>
<Route path="/:id" component={Child} />
</div>
</Router>
);
const Child = ({ match }) => (
<div>
<h3>ID: {match.params.id}</h3>
</div>
);
export default ParamsExample;
向路由元件傳遞search參數
- 路由連結(攜帶參數): < Link to="/demo?id=$ {info.id}&name=${info.name}" >{info.name}</ Link >
- 注冊路由(無需接收參數): < Route path="/demo" component={Demo} />
- 接受參數:const {search} = this.props.location , const {id,name} = qs.parse(search.slice(1))
備注:路由元件接受參數由于是search參數:"?id=Netflix&name=Netflix"(urlencoded編碼字元串),是以需要一個【querystring庫】轉化成"{id:‘Netflix’,name:‘Netflix’}"的格式
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
//不用安裝,react腳手架已經下載下傳好了,直接引入用
//将“?id=Netflix&name=Netflix”轉換成一個對象{id:'Netflix',name:'Netflix'}的庫
import qs from "querystring";
//舉例子說明querystring庫的使用
let obj= {name:'tom',age:18}
console.log(qs.stringify(obj)) //name=tom&age=18 urlencoded編碼
let str = "name=tom&age=18"
console.log(qs.parse(str)) // {name:'tom',age:18}
export default class Test extends React.Component {
state = {
infos:[
{id:'Netflix',name:'Netflix'},
{id:'Zillow Group',name:'Zillow Group'}
]
}
render(){
const {infos} = this
return (
<Router>
<div>
<h2>Accounts</h2>
<ul>
{
infos.map((info) => {
return (
<li>
<Link to="/demo?id=${info.id}&name=${info.name}">{info.name}</Link>
</li>
)
})
}
</ul>
{/* search參數無需接受 */}
<Route path="/demo" component={Demo} />
</div>
</Router>
)
}
}
class Demo extends React.Component{
const {search} = this.props.location
const {id,name} = qs.parse(search.slice(1))
render(){
return (
<div>
<h3>ID: {id}</h3>
<h3>NAME: {name}</h3>
</div>
)
}
}
向路由元件傳遞state參數
- 路由連結(攜帶參數): < Link to={{pathname:’/demo’,state:{id:info.id,name:info.name}}} >{info.name}</ Link >
- 注冊路由(無需接收參數): < Route path="/demo" component={Demo} />
- 接受參數: const {id,name} = this.props.location.sate
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
export default class Test extends React.Component {
state = {
infos:[
{id:'Netflix',name:'Netflix'},
{id:'Zillow Group',name:'Zillow Group'}
]
}
render(){
const {infos} = this
return (
<Router>
<div>
<h2>Accounts</h2>
<ul>
{
infos.map((info) => {
return (
<li>
<Link to={{pathname:'/demo',state:{id:info.id,name:info.name}}} >{info.name}</Link>
</li>
)
})
}
</ul>
{/* state參數無需接受 */}
<Route path="/demo" component={Demo} />
</div>
</Router>
)
}
}
class Demo extends React.Component{
//接收state參數
const {id,name} = this.props.location.sate
render(){
return (
<div>
<h3>ID: {id}</h3>
<h3>NAME: {name}</h3>
</div>
)
}
}
程式設計式路由導航
最常用的方法:replace()、push()、goback()、go()
注意隻有路由元件才能使用以上程式設計式路由導航
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
export default class Test extends React.Component {
state = {
infos:[
{id:'Netflix',name:'Netflix'},
{id:'Zillow Group',name:'Zillow Group'}
]
}
clickKip = (id,name) => {
this.props.history.push(`/demo/${id}/${name}`) //無曆史記錄的跳轉,可以回退
this.props.history.replace(`/demo/${id}/${name}`) //替換路由跳轉
}
render(){
const {infos} = this
return (
<Router>
<div>
<h2>Accounts</h2>
<ul>
{
infos.map((info) => {
return (
<li>
<Link onClick={()=>this.clickKip(info.id,info.name)}>{info.name}</Link>
</li>
)
})
}
</ul>
{/* state參數無需接受 */}
<Route path="/demo" component={Demo} />
</div>
</Router>
)
}
}
class Demo extends React.Component{
//接收state參數
const {id,name} = this.props.match.params
render(){
return (
<div>
<h3>ID: {id}</h3>
<h3>NAME: {name}</h3>
</div>
)
}
}
withRouter
您可以通過 withRouter 高階元件通路 history 對象的屬性和最近的 的 match 。 當路由渲染時, withRouter 會将已經更新的 match , location 和 history 屬性傳遞給被包裹的元件。
import React from "react";
import { withRouter } from "react-router-dom";
//一般元件
class Demo extends React.Component{
...
}
export default withRouter(Demo )
- withRouter的傳回值是一個新元件;
- withRouter可以加工一般元件,讓一般元件擁有路由元件所特有的API,可以向路由元件一樣可以通路到match , location 和 history 屬性,元件内也可以使用程式設計式導航;
BrowserRouter和HashRouter的差別
1.底層原理不一樣
- BrowserRouter使用的是H5的history的API,不相容IE9以及以下的版本
- HashRouter使用的是url的哈希值
2.url表現形式不一樣
- BrowserRouter的路徑上沒有#,例如: http://localhost:3005/demo
- HashRouter的路徑帶#,例如: http://localhost:3005/#/demo
3.重新整理後對路由state參數的影響
- BrowserRouter沒有任何影響,因為state儲存在history對象中
- HashRouter重新整理後會導緻state參數的丢失
4.備注:HashRouter可以用來解決一些路徑錯誤相關的問題