react动态路由组件的封装
我这篇比较全面
首先下载包
npm i react-router-dom@5
这里为什么要用5的版本为啥不用最新的,原因在于老版本跟新版本写法不一样
老版本
import { HashRouter, Route, Switch, Redirect } from 'react-router-dom';
render() {
return (
<HashRouter>
<Switch>
<Route exact path="/home" component={Home} />
</Switch>
</HashRouter>
)
}
新版本
import { HashRouter, Route, Routes, Navigate} from 'react-router-dom';
render() {
return (
<HashRouter>
<Routes>
<Route path="/login" element={<Login/>}></Route>
</Routes>
</HashRouter>
)
}
区别 以前是用
Switch
包裹现在用的是Routes
以前 组件是component=函数名,现在要写成组件形式并且是element=<组件名/>,以前重定向Redirect
,现在Navigate
了解以上这些 我们这里开始封装一些组件
这里我讲解两种方式
第一种异步加载路由
1.首先创建一个异步加载路由函数
asyncComponent.js
import React from "react";
export default function asyncComponent(importComponent) {
class AsyncComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
component: null
};
}
async componentDidMount() {
const { default: component } = await importComponent();
this.setState({ component });
}
render() {
const Component = this.state.component;
return Component ? <Component {...this.props} /> : null;
}
}
return AsyncComponent;
}
2.创建路由容器文件
map.js
import asyncComponent from "./until/asyncComponent"; //引入刚才的函数
export default [
{
path: "/home",
component: asyncComponent(() =>
import(
/* webpackChunkName: "modules/digitalVillage/index" */ "../views/home/index"
)
)
},
{
path: "/CodeScan/houseCode",
component: asyncComponent(() =>
import(
/* webpackChunkName: "modules/digitalVillage/index" */ "../views/myself/index"
)
)
},
]
3.创建视图路由文件
touterView.js
//这里用的5点几版本 由于最新的里面要传组件 我传过去了但是没显示,有兴趣的可以去试一下最新的路由方式
import React from 'react';
import { HashRouter, Route, Switch, Redirect } from 'react-router-dom';
//这里定义重定向跟普通函数跳转
export const routeCreate = (props) => {
return { type: 'Route', props };
};
export const redirectCreate = (props) => {
return { type: 'Redirect', props };
};
//最终返回的路由
export default class extends React.Component {
renderItem = (item, index) => {
let Component = null;
const { type, props } = item;
if (type === 'Route') {
Component = Route;
} else if (type === 'Redirect') {
Component = Redirect;
}
return Component ? (
<Component key={index} {...props} />
) : null;
};
componentDidCatch(error, info) {
console.error(error);
console.log(info);
}
render() {
const { data } = this.props;
return (
<HashRouter>
<Switch>
{data.map((item, index) => this.renderItem(item, index))}
</Switch>
</HashRouter>
)
}
}
4.创建路由中间件
index.js
import React from 'react';
import RouterView, { routeCreate, redirectCreate } from './until/routerView';
import routerMap from './map';
//
const routerData = [
redirectCreate({ from: '/', to: '/CodeScan/houseCode', exact: true }),//重定向页
...routerMap.map(routeCreate)
];
export default class extends React.Component {
render() {
return (
<RouterView data={routerData} />
);
}
}
最终在app里面加载就好了
第二种方式路由的懒加载
1.创建一个懒加载lazy函数
npm i react-loadable
import React from 'react'
import Loadable from 'react-loadable';
import loadCom from "../../views/load" //懒加载等待页面自己定义
//过场组件默认采用通用的,若传入了loading,则采用传入的过场组件
export default (loader, loading = loadCom) => {
return Loadable({
loader,
loading
});
}
2.mapjs 路由容器
import loadable from './until/loadLazy'
export default [
{
path: "/home",
component: loadable(() => import('../views/home'))
},
]
3.视图路由跟路由中间件是一样的
以上就是路由懒加载跟异步的封装