1.介绍react-router
自从新版本(好像是4)发布后,如果我们想要在浏览器中使用react-router的话,那么所需要安装的依赖包是react-router-dom,同时为了增加对typescript的支持,我们还需要yarn add @types/react-router-dom –dev。
react-router-dom里面的两个关键性组件BrowserRouter和Route组件,其中BrowserRouter是top-level component,它会根据path来决定哪个子Route组件将会被渲染。下面是一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import * as React from "react"; import * as ReactDOM from "react-dom"; import { BrowserRouter as Router, Route } from "react-router-dom"; import Page1 from "./page/1"; import Page2 from "./page/2";
const Routes: React.SFC = () => { return ( <Router> <div> <Route path="/1" component={Page1} /> <Route path="/2" component={Page2} /> </div> </Router> ); }
ReactDOM.render(<Routes />, document.getElementById("root") as HTMLElement);
|
2.使用Link进行导航
不多说,来自react-router-dom,见例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import * as React from "react"; import { BrowserRouter as Router, Route, Link } from "react-router-dom"; import Page1 from "./page/1"; import Page2 from "./page/2";
const Routes: React.SFC = () => ( <Router> <div className="header"> <Link to="/1">page1</Link> <Link to="/2">page2</Link> </div> <div className="content"> <Route path="/1" component={Page1} /> <Route path="/2" component={Page2} /> </div> </Router> );
|
3.介绍一下NavLink
相比Link,它可以接受一个activeClassName作为props,能够更加方便的定制当前路由tab处于焦点状态时的样式效果。
4.路由通配符之RouteComponentProps
关键词:路由通配符;RouteComponentProps;props.match.params,下面是一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import * as React from "react"; import { RouteComponentProps } from "react-router";
type Props = RouterComponentProps<{id: string}>;
const Page21 = React.SFC<Props> = props => { return (<h1>{props.match.params.id}</h1>); }
export default Page21;
// routes.ts <Route exact={true} path="/2" component={Page2} /> <Route path="/2/:id" component={Page21} />
|
注意对于上面的这个例子,对于path是/2的这个Route,增加了一个exact={true},如果不加的话,那么对于路由/2/3 将会既渲染Page2组件同时也会渲染Page21组件。以及,路由通配符所对应的变量的数据类型要么是字符串类型或者是undefined,所以必要的话,使用的时候需要做一个类型转换。另外,如果你定义组件的state类型的话,但是在构造函数里面又没有初始化的话,将会报错,为了避免这种在构造函数可能无法获取到值的情况下,建议将这个state作为可选state。
5.Switch component
Switch component的作用,对于Switch component的子Route component来说,谁最先被匹配到,那么谁显示谁,并且最多匹配一个。我们可以使用Switch来做些什么呢?可以用来实现404页面效果,把404组件作为Switch组件的最后一个子Route即可。
1 2 3 4 5 6 7 8 9
| import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
<Router> <Switch> <Route path="/2" component={page2} /> <Route path="/2/:id" component={page21} /> <Route component={notFound} /> </Switch> </Router>
|
6.Redirect之权限验证:
如果某个路由是必须要登录之后才能够访问到的话,那么很显然此时必须做一个登录状态的验证,如果没有登录的话,那么就跳转到登录页面,下面是一个示意例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { BrowserRouter as Router, Route, Redirect, Switch } from "react-router-dom";
const Routes: React.SFC = () => { const [ isLogin, setLogin ] = React.useState(false); return ( <Router> <Switch> <Route path="/1"> { isLogin ? <Page1 /> : <Redirect to="/login" /> } </Route> <Route path="/2" exact={true} component={Page2} /> <Route path="/2/:id" component={Page21} /> <Route path="/login" component={Login} /> <Route component={NotFound} /> </Switch> </Router> ); };
|
7.react-router-dom获取查询字符串
关键词:RouteComponentProps,props.location.search;而对于路由匹配来说,关键词则是RouteComponentProps,props.match.params
直接举例如下所示:
1 2 3 4 5 6 7 8 9 10
| import * as React from "react"; import { RouteComponentProps } from "react-router-dom";
const Search: React.SFC<RouterComponentProps> = props => { const obj = new URLSearchParams(props.location.search); const what = obj.get("what") || ""; return (<h1>{what}</h1>); }
export default React.memo(Search);
|
8.lazy load component
react16内置了对lazy component的支持,只有当在必要的时候才会加载对于的路由组件。关键词:Suspense,React.lazy,fallback
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import * as React from "react"; const Suspense = React.Suspense;
const Page1 = React.lazy(() => import("./page/1"));
const Routes: React.SFC = () => ( <BrowserRouter> <Switch> <Route path="/1"> { variable ? <Suspense fallback={<h1>Loading</h1>}><Page1 /></Suspense> : <Redirect to="/login" /> } </Route> </Switch> </BrowserRouter> );
|