react代码分割(二)之react.lazy和Suspense组合

之前介绍过代码分割的插件react-loadable:react代码分割(一)之react-loadable,这次介绍一下react官方提供的方法

动态import语法

在react官网的代码分割部分阐述了为什么要代码分割,以及代码分割实现需要靠动态import进行
在这里插入图片描述

为了方便使用,react自身提供了lazy和suspense组合使用进行代码分割

使用样例

首先使用lazy引入组件

// router.ts
import { lazy } from "react"
const Home = lazy(() => import("../views/Home"));
const Login = lazy(() => import("../views/Login"));
const NotFound = lazy(() => import("../components/NotFound"));

export default [
	{ path: "/", key: 1, name: "首页", component: Home, auth: true },
	{ path: "/home", key: 2, name: "首页", component: Home, auth: true },
	 { path: "/login", key: 2, name: "登录", component: Login },
    { path: "*", key: 3, name: "notfound", component: NotFound }
]

使用router管理页面

import React, { Suspense } from "react";
import { Switch, Route, Redirect, HashRouter } from "react-router-dom";
import Routers from "./router";
import { connect } from 'react-redux'
import MyErrorBoundary from "../components/ErrorBoundary"
import { loginState } from "@/store/reducer/loginReducer"
import Navbar from "@/components/Navbar";
import { LoadingOutlined } from "@ant-design/icons"

export interface routerProps {
    login: loginState
}

const RouterView: React.FC<routerProps> = (props) => {
    const _loginProps = props.login

    return (<div style={{ width: "100%", height: "100%" }}>
        <MyErrorBoundary>
            <HashRouter>
                {/* 导航跳转必须包裹在router中,不然组件无法使用useHistory和useLocation */}
                <Navbar />
                {/* fallback控制异步加载组件时等待的动画 */}
                <Suspense fallback={< div style={{ width: "100%", height: "100%", fontSize: "50px", display: "flex", justifyContent: "center", alignItems: "center", color: "rgba(49, 213, 248, 1)" }}>
                    <LoadingOutlined />
                </div>}>
                    <Switch>
                        {Routers.map((item) => {
                            const TempComponent = item.component;
                            // 根据组件是否需要权限验证以及登录状态控制页面显示
                            return <Route key={item.name} path={item.path} exact render={(props) =>
                            (!item.auth ? (<TempComponent {...props} />) : (_loginProps.status ? <TempComponent {...props} /> : <Redirect to={{
                                pathname: '/login',
                                state: { from: props.location }
                            }} />)
                            )} />
                        })}
                    </Switch>
                </Suspense>
            </HashRouter>
        </MyErrorBoundary>
    </div>)
}
const mapStateToProps = (state: any) => {
    return {
        login: state.login
    }
}
export default connect(mapStateToProps)(RouterView);

Tips

1.与路由相关的组件如NavBar一定要放在Router下哦,不然获取不到路由相关的值
2.在路由管理界面也可以加上错误边界相关的组件,可以防止部分 UI 的 JavaScript 错误导致整个应用崩溃。

// ErrorBoundary.tsx
import React from "react";
import "./index.scss"
export default class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { error: null, errorInfo: null  };
    }

    // static getDerivedStateFromError(error) {
    //     // 更新 state 使下一次渲染能够显示降级后的 UI
    //     return { hasError: true };
    // }

    componentDidCatch(error, errorInfo) {
        // 你同样可以将错误日志上报给服务器
        console.log(error, errorInfo);
        this.setState({
            error: error,
            errorInfo: errorInfo
        })
    }

    render() {
        if (this.state.errorInfo) {
            // 你可以自定义降级后的 UI 并渲染
            return <div className="errorboundary">
                <h2>页面错误</h2>
                <details style={{ whiteSpace: 'pre-wrap' }}>
                    {this.state.error && this.state.error.toString()}
                    <br />
                    {this.state.errorInfo.componentStack}
                </details>
            </div>;
        }

        return this.props.children;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

霜叶w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值