13.代码分割之import 之静动态导入
import 是关键字,不是function
staic import 静态导入
import *** from ''./a.js" 或 import './a.js'
dynamic import 动态导入
import () 返回的是个promise,需要拿到返回的东西,需要用到 await,根据条件或按需的模块导入
async importModule() {
const { plus } = await import("./utils.js");
console.log(plus(1, 2));
}
应用场景:
1.模块太大,使用性很低的模块是存在的,这些是不需要马上加载的
2.模块的导入用的大量的系统内存
3.模块需要导步获取
4.导入的模块需要动态的构建路径 import ( './' +a + b +'.js')
5.模块中的代码需要和序触发了某些条件才动行的
注:不要滥用动态导入,静态导入是有利于初使化依赖,静态的程序分析和 tree shaking 静态导入会使其更好的工作
使用动态 import 条件:
- create react app --> 直接可以使用 import()
- 手动搭建的需要做webpack 的配置,查看代码分割的指南
- babel 解析 import() 依赖 @babel/plugin-syntax-dynamic-import
14.代码分割之lazy:suspense与路由懒加载
lazy 内置方法 / suspense React内置组件,挂载到React
lazy 是React 提供给你的懒(动态)加载组件的方法 React.lazy()
- 参数:接收一个动态导入组件 import() 函数,该函数返回一个promise (IE11要用 polyfill),promise 会 resolve 一个默认导出react的组件,所以导出react 组件要用 export default
- 减少打包体积,对初次渲染不适用的组件延迟加载
- 依赖内置组件 Suspense,给lazy 加上loading指示器组件的一个容器组件,suspense 目前只和lazy醒合实现组件等加载指示器的功能
- 服务端渲染 lazy是支持,要使用 loadable components
import React, { Component } from "react";
import Loading from './components/loading.jsx'
const LazyComponent = React.lazy(()=>import('./components/lazytest.jsx'))
export default class App extends Component {
render() {
return (
<div>
<React.Suspense fallback={<Loading/>}>
<LazyComponent/>
</React.Suspense>
</div>
);
}
}
懒加载路由
react 引入路由
1.安装 yarn add react-router-dom react-router
2.组件包裹在 BrowserRouter 里
入口文件 index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { x } from "react-router-dom";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
app.jsx
import React, { Component, lazy, Suspense } from "react";
import { Switch, Route } from "react-router";
import Loading from "./components/loading.jsx";
export default class App extends Component {
render() {
return (
<div>
<Suspense fallback={<Loading />}>
<Switch>
<Route
path="/page1"
component={lazy(() => import("./view/page1"))}
></Route>
<Route
path="/page2"
component={lazy(() => import("./view/page2"))}
></Route>
<Route
path="/page3"
component={lazy(() => import("./view/page3"))}
></Route>
</Switch>
</Suspense>
</div>
);
}
}
15.错误边界与使用技巧
- React 16新增的功能
- 防止某个组件的UI渲染错误导致整个应用崩溃
- 子组件发生js错误,有备用的渲染UI
- 错误边界 组件只能用class组件来写
- 如果多个错误边界组件,则从里层错误出发,向上冒泡出发捕获
- 错误边界组件捕获时机:
- 渲染时
- 生命周期函数中
- 组件树的构造函数
static getDerivedStateFromError(error)
- 静态的,生命周期函数,用于渲染备用的UI,获取补获错误,修改错误状态
- 参数:子组件抛出的错误
- 返回值:新的state
- 渲染阶段调用,不允许出现副作用,异步(settimeout等)
- 无法补获的错误:
- 事件处理函数
- 异步代码 setTimeout ajax 等
- 服务端渲染
- 错误边界组件内部有错误
componentDidCatch(error,info)
- 边界错误组件捕获异常,并进行后续处理,错误信息获取,运行副作用
- 在组件抛出错误后调用
- 参数:error 抛出的错误,info:组件引发错误相关信息,组件栈
import React, { Component } from "react";
export default class ErrorBoundary extends Component {
state = {
hasError: false,
};
static getDerivedStateFromError(error) {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <h1>this is error UI</h1>;
}
return this.props.children;
}
}
16.命名导出
lazy只支持默认导出的组件,
写一个中间文件,
export {
test1 as default,
test2 as default
}