React-Router
简介
-
react-router 5.x.x
-
路由应该在一处渲染,后面自己构建路由组件
-
一切皆组件
-
react-router包含了四个包
- react-router
- react-router-dom 实际使用
- react-router-native react-native【react移动端开发框架】当中使用的
- react-router-config 静态路由的配置
-
路由的基本原理
-
hash模式 (hashchange)
-
history模式 (popstate + history api)
-
React-Router-Dom 快速入门(一级路由)
官方文档: https://reacttraining.com/react-router/web/api/Route
1. 安装react-router-dom
// 安装react-router-dom $ yarn add react-router-dom // 安装Ts类型声明 $ yarn add @types/react-router-dom
2. 确定路由模式
src/index.tsx 书写以下代码
import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; import "antd/dist/antd.css"; //todo 1.确定路由模式 import { // HashRouter, //todo 表示使用hash模式 BrowserRouter, //todo 表示使用history模式 } from "react-router-dom"; ReactDOM.render( <React.StrictMode> <BrowserRouter> <App /> </BrowserRouter> </React.StrictMode>, document.getElementById("root") ); reportWebVitals();
3. 打造路由组件
在src/router/index.tsx
//todo 打造路由组件 const RouterComp = () => { ... return <div>...</div>; }; export default RouterComp;
4. 打造导航组件
src/common/components/AppNav/index.tsx (因为导航组件是公共组件,所以放在公共文件夹)
//todo 打造导航组件 const AppNav = () => { ... return <div>...</div>; }; export default AppNav;
5.使用路由和导航组件
在src/App.tsx中导入和使用路由和导航组件
import React, { FC } from "react"; import AppNav from "./common/components/AppNav"; import RouterComp from "./router"; const App: FC = () => { return <div> {/* 导航组件 */} <AppNav/> {/* 路由组件 */} <RouterComp/> </div>; }; export default App;
6.创建路由表
在src/router/routes.ts
前提:在src/pages下已经构建好了各页面组件
在react中可以自行构建路由表, react-router是通过配置渲染组件
使用**lazy(()=> import(’…/pages/页面组件名))**来得到组件
注意为routes表定义类型 src/router/interface.ts
import React from 'react'; export interface IRoutes{ path:string; component:React.LazyExoticComponent<React.FC<{}>>; title?:string; }
// 创建路由表 import { IRoutes } from './interface'; import { lazy } from "react"; const routes:IRoutes[]=[ { path:'/home', component:lazy(()=> import('../pages/Home')), title:'主页' }, { path:'/myList:id', component:lazy(()=> import('../pages/MyList')), title:'分类' }, // ...... { path:'*', component:lazy(()=> import('../pages/NotFound')) }, ]; export default routes;
7. 实现路由组件
实现流程
- 按需导入路由功能性组件和Ts类型…
- 定义路由列表数据
- 定义渲染函数
- 使用useMemo处理渲染函数
- 使用Suspense -> Switch - > Redirect 渲染
// 导入功能性组件和方法(react) import { Suspense, useMemo, useState } from "react"; // 导入路由实例 import routes from "./routes"; // 导入路由TS类型 import { IRoutes } from "./interface"; // 导入功能性组件(react-router-dom) import { Redirect, Route, Router, Switch } from "react-router-dom"; // 导入antd组件 import { Spin } from "antd"; const RouterComp = () => { // 定义路由列表数据(默认值为路由实例,用于渲染路由组件) const [routeList] = useState<IRoutes[]>(routes); // 定义路由组件的渲染函数 const renderRoute = () => { return routeList.map((item, index) => ( // Router组件用于根据path和components属性渲染路由 <Route path={item.path} component={item.component} key={index} /> )); }; // 使用useMemo得到记忆值来优化组件性能 当路由列表数据改变时,才执行渲染, const memoRoute = useMemo(() => { return renderRoute(); }, [routeList]); return <div> {/* Suspense:转场组件 搭配lazy实现路由懒加载 fallback属性为加载中的UI界面 */} <Suspense fallback={ <div> <Spin size="large" /> </div> }> {/* Switch: 一次只渲染一次组件 */} <Switch> {/* Redirect: 重定向组件 from表示匹配到的路由地址 to表示跳转的路由地址 exact表示精准匹配* 如果不加exact ,那么只要路由路径中有 / 就全会跳到/home/} <Redirect from='/' to='/home' exact /> { memoRoute } </Switch> </Suspense> </div>; }; export default RouterComp;
8.实现导航组件
import React, { FC, useMemo, useState } from "react"; import {NavLink} from 'react-router-dom' import routes from "../../../router/routes"; import {IRoutes} from '../../../router/interface' import styles from './style.less' const AppNav: FC = () => { // 定义导航列表数据(默认值为路由实例,用于渲染导航组件) const [navs,setNavs]=useState<IRoutes[]>(routes.slice(0,-1)) // 定义导航组件渲染函数 const renderNavs=()=>{ return navs?.map((item:IRoutes,index)=>( <li key={index}> // 使用NavLink组件渲染导航 使用to=跳转路由 <NavLink activeClassName='nav_active' to={item.path}>{item.title}</NavLink> </li> )) } // 使用useMemo得到记忆值来优化组件性能 当导航列表数据改变时,才执行渲染 const memoNavs= useMemo(()=>{ return renderNavs() },[navs]) // 渲染输出导航列表 return <div className={styles.app_nav}> <ul className={styles.app_nav_list}> {memoNavs} </ul> </div>; }; export default AppNav;
二级路由
页面跳转
核心:使用useHistory来实现页面跳转
1.导入useHistory,得到history对象实例
import { useHistory } from "react-router-dom";
const history=useHistory()
2.返回前进和刷新
<button onClick={()=>{history.goBack()}}>返回</button>
<button onClick={()=>{history.go(1)}}>返回</button>
<button onClick={()=>{history.go(0)}}>页面刷新</button>
3.页面跳转
声明式跳转: <Link to='/topDetail'>去置顶详情</Link>
声明式跳转: <NavLink to='/topDetail'>去置顶详情</NavLink>
命令式跳转: <button onClick={()=>{history.push('/topDetail')}}>push跳转</button>
命令式跳转: <button onClick={()=>{history.replace('/topDetail')}}>replace跳转</button>
动态路由
使用 users/:参数