react-router-dom 的使用
index.tsx
import React from 'react';
import {
BrowserRouter,
HashRouter,
Route,
Link,
NavLink,
Switch,
Redirect,
} from 'react-router-dom';
import Header from './Comps/Header';
import MyNavLink from './Comps/MyNavLink';
import './index.css';
import About from './About';
import Home from './Home';
import News from './News';
const RouterDome: React.FC = () => {
/*
* react-router-dom 的使用,当前版本 5.3.0
*
* BrowserRouter 历史模式路由, HashRouter hash模式路由
* 使用时 Route 时必须要用 BrowserRouter 或 HashRouter 包裹,而且只能有一个,可以直接包裹在App上。
*
* NavLink 和 Link 的区别
* NavLink 可以设置 activeClassName 属性,当该属性与当前路径匹配时,会自动将属性内的类名添加到元素上
* <NavLink activeClassName="active" className="route-li" to="/about">
*
* Switch 的 作用
* 可以提高路由匹配的效率
* 当多个 Route 存在相同的 path 时,那么这几个组件将会同时显示
* 如下:(Home 组件 和 About 组件 将同时显示)
* <Route path="/home" component={Home}></Route>
* <Route path="/home" component={About}></Route>
* 若 使用 Switch 将 Route 包裹,那么当路由匹配当第一个组件时,将不再往下配置,则只会显示 Home 组件
*
* router 的 模糊匹配(默认模式)和 严格匹配
*
* 模糊匹配(匹配顺序是从左往右进行的)
* 例子1 (匹配成功)
* <NavLink to="/home/a/b/c">News</NavLink>
* <Route path="/home" component={Home}></Route>
*
* 例子2 (匹配失败)
* <NavLink to="/a/home/c">News</NavLink>
* <Route path="/home" component={Home}></Route>
*
* 严格模式
* 开启严格匹配模式,在 Route 组件内 添加 exact 即可, 且 to 和 path 必须相同才能匹配成功
* 如:
* <NavLink to="/about">News</NavLink>
* <Route exact path="/about" component={About}></Route>
* 需注意一般情况下,不要开启严格匹配模式,可能会导致二级路由匹配失败
*
* Redirect 路由重定向
* 用法 <Redirect to="/home"></Redirect>,在 to 中指定需要展示的组件
* 当所有点路由都匹配不上时,该组件才会生效
*
* 嵌套路由
* 子级路由必须以父级路由名称为开头,而且父级路由不能开启 exact 模式
* 如:
* 父级
* <Route path="/news" component={News}></Route>
* 子级
* <Route path="/news/compA" component={CompA}></Route>
* <Route path="/news/compB" component={CompB}></Route>
*
* router params 参数
* 传参:<NavLink to="/news/compA/a">compA</NavLink>
* 接收:<Route path="/news/compA/:type" component={CompA}></Route>
* 获取参数:通过 props.match.params 即可拿到 type = a
*
* router search 参数
* 传参:<NavLink to="/news/compB?name=compB&type=B">compB</NavLink>;参数通过 ? 拼接在路径上,多个参数用 & 隔开,且无需去接收
* 获取参数:通过 props.location.search 获取,需注意这里获取到的参数是字符串 ?name=compB&type=B
* 示例:
* import React from 'react';
* import qs from 'querystring'; // 无需安装,此为自带的库
*
* interface ICompB {
* [propName: string]: any;
* }
* const CompB: React.FC<ICompB> = (props) => {
* const { search } = props.location;
* const query = qs.parse(search.slice(1));
* console.log(query); // { name: 'compB', type: 'B' }
* return <h3>this is CompB</h3>;
* };
* export default CompB;
*
* router state 参数
* 注意:HashRouter 模式下,刷新会导致 state 数据丢失,因此 HashRouter 模式下不推荐使用该方法传参
* 示例:
* 传参:<NavLink to={{ pathname: '/news/compC', state: { name: 'compC', type: 'C' } }}>compC</NavLink>
* 获取参数:
* import React from 'react';
* const CompC: React.FC = (props) => {
* console.log((props as any).location.state); // {name: 'compC', type: 'C'}
* return <h3>this is CompC</h3>;
* };
* export default CompC;
*
* router push 和 replace
* push(默认模式),会在浏览器上留下记录
* replace 则是替换当前路径,且不会在浏览器留下记录
* 开启replace模式:
* 如:<NavLink replace to="/news/compA/a">compA</NavLink>,<Link replace></Link>
*
* 编程式路由的使用
* 先熟悉下 props.history 几个常用的属性
* history: {
* go: ƒ go(n),
* goBack: ƒ goBack(),
* goForward: ƒ goForward(),
* push: ƒ push(path, state),
* replace: ƒ replace(path, state)
* }
* go 的使用
* n 为正数则往后退,负数则往前退
* 示例:(props as any).history.go(n);
*
* goBack 的使用
* 往前退一步
* 示例:(props as any).history.goBack();
*
* goForward 的使用
* 往后退一步
* 示例:(props as any).history.goForward();
*
* push 的使用
* 第一种情况,params 参数
* 示例:(props as any).history.push('/news/compA/a');
* 第二种情况,search 参数
* 示例:(props as any).history.push('/news/compB?name=compB&type=B');
* 第三种情况,state 参数
* 示例:(props as any).history.push('/news/compC', { name: 'compC', type: 'C' });
*
* replace 和 push 使用基本相同,只不过是 把 push 替换成了 replace,参考上面案例。
* 需注意以上的路由方法只能在路由组件中使用
*
* withRouter
* 作用:使一般组件也能像路由组件一样,调用 history 身上的方法
*/
return (
<BrowserRouter>
<div className="router-demo">
{/* 一般组件 */}
<Header></Header>
<div className="router-main">
<div className="left">
<ul>
{/* <Link to="./home" className="route-li">Home</Link> */}
<li>
<NavLink activeClassName="active active2" className="route-li" to="/home">
Home
</NavLink>
</li>
<li>
<NavLink activeClassName="active" className="route-li" to="/about">
About
</NavLink>
</li>
<li>
<MyNavLink to="/news">News</MyNavLink>
</li>
</ul>
</div>
<div className="right">
<Switch>
{/* <Route path="/home" component={Home}></Route> */}
<Route path="/home" component={Home}></Route>
<Route path="/about" component={About}></Route>
<Route path="/news" component={News}></Route>
<Redirect to="/home"></Redirect>
</Switch>
</div>
</div>
</div>
</BrowserRouter>
);
};
export default RouterDome;
News 组件
import React from 'react';
import { NavLink, Switch, Route, Redirect } from 'react-router-dom';
import CompA from './CompA';
import CompB from './CompB';
import CompC from './CompC';
import './index.css';
const News: React.FC = (props) => {
function onGo(n: number) {
// n 为正数则往后退,负数则往前退
(props as any).history.go(n);
}
function goBack() {
// 往前退一步
(props as any).history.goBack();
}
function goForward() {
// 往后退一步
(props as any).history.goForward();
}
function onPushParams() {
(props as any).history.push('/news/compA/a');
}
function onPushSearch() {
(props as any).history.push('/news/compB?name=compB&type=B');
}
function onPushState() {
(props as any).history.push('/news/compC', { name: 'compC', type: 'C' });
}
return (
<div className="news-content">
<h2>this is News</h2>
<button onClick={() => onGo(-1)}>go -1</button>
<button onClick={() => onGo(1)}>go 1</button>
<button onClick={() => goBack()}>goBack 往前退一步</button>
<button onClick={() => goForward()}>goForward 往后退一步</button>
<button onClick={() => onPushParams()}>push params 传参</button>
<button onClick={() => onPushSearch()}>push search 传参</button>
<button onClick={() => onPushState()}>push state 传参</button>
<ul>
<li>
<NavLink to="/news/compA/a">compA</NavLink>
</li>
<li>
<NavLink to="/news/compB?name=compB&type=B">compB</NavLink>
</li>
<li>
<NavLink to={{ pathname: '/news/compC', state: { name: 'compC', type: 'C' } }}>
compC
</NavLink>
</li>
</ul>
<Switch>
<Route path="/news/compA/:type" component={CompA}></Route>
<Route path="/news/compB" component={CompB}></Route>
<Route path="/news/compC" component={CompC}></Route>
<Redirect to="/news/compA/a"></Redirect>
</Switch>
</div>
);
};
export default News;
Header 组件
import React from 'react';
import { withRouter } from 'react-router-dom';
const Header: React.FC = (props) => {
function onGo(n: number) {
// n 为正数则往后退,负数则往前退
(props as any).history.go(n);
}
return (
<>
<h2>React Router Dome</h2>
<button onClick={() => onGo(-1)}>go -1</button>
<button onClick={() => onGo(1)}>go 1</button>
</>
);
};
export default withRouter(Header);
浙公网安备 33010602011771号