代码分割
import 静动态导入
- 静态导入:static import
import xxx from 'xxx'
导入并加载时,导入的模块会被编译,不是按需编译 - 动态导入:dynamic import
import('xxx')
根据条件或按需的模块导入
动态导入应用场景:
- 模块太大了,使用可能性很低的模块是存在的,这些模块不需要马上加载
- 模块的导入占用大量的系统内存
- 模块需要异步获取
- 导入模块时,需要动态构建路径
import('./' + a + b + '.js')
// 动态说明符(静态导入只支持静态说明符:'./a/b/c.js'
) - 模块中的代码需要程序触发了某些条件才运行
不要滥用动态导入,静态导入是有利于初始化依赖,静态的程序分析和
tree sharking
静态导入会使其更好的工作
babel
解析 import()
依赖 @babel/plugin-syntax-dynamic-import
// index.module
export default class Test{
constructor(){
console.log('new Test');
}
}
// 动态导入返回一个 promise,res 接收模块的默认导出
import("./index.module").then((res) => {
console.log(res);
new res.default();
});
lazy 内置方法 / Suspense React 内置组件
lazy
是 React
提供的懒(动态)加载组件的方法 React.lazy(函数:动态导入组件)
,该函数返回一个 Promise
减少打包体积,对初次渲染不适用的组件延迟加载
依赖内置组件 Suspense
,给 lazy
加上 loading
指示器的一个容器组件
// ./lazy/Loading.jsx
export default class Loading extends React.Component {
render() {
return <div>Loading...</div>;
}
}
// ./lazy/Main.jsx
export default class Main extends React.Component {
render() {
return <div>Main</div>;
}
}
// index.jsx
// lazy 接收一个动态导入组件的函数
// 该函数返回一个 promise
// promise 会 resolve 一个默认导出(export default)的 React 组件
// Suspense 只和 lazy 配合实现组件等待加载指示器的功能
import Loading from "./lazy/Loading";
const MainComponent = React.lazy(() => import("./lazy/Main"));
class App extends React.Component {
render() {
return (
<React.Suspense fallback={Loading}>
<MainComponent />
</React.Suspense>
);
}
}
ReactDOM.render(<App />, document.querySelector("#app"));
yarn add react-router react-router-dom -D
错误边界
React 16
增加的组件
- 防止某个组件的
UI
渲染错误导致整个应用崩溃 - 子组件发生
js
错误,有备用的渲染UI
- 错误边界其实是一个组件,只能用
class
来写
getDerivedStateFromError(error)
参数:子组件抛出的错误
返回新的 state
作用:获取捕获的错误,修改错误装填
渲染阶段调用,不允许出现副作用:setTimeout
、requestAnimationFrame
错误边界组件捕获错误的时机:渲染时、生命周期函数中、组件树的构造函数中
错误边界组件可以嵌套使用,且有冒泡机制,捕获的错误会一直往上抛,也就是说,里面的错误边界组件报错了,外层的错误组件可以捕获到
无法捕获的场景:
- 事件处理函数内部错误
- 异步代码
setTimeout
、ajax
、requestAnimationFrame
- 服务端渲染(因为触发更新只能在客户端进行,不能在serve端进行)
- 错误边界组件内部错误
componentDidCatch
原型上的方法,componentDidCatch(error, info)
参数:
-
error
:抛出的错误 - 组件引发错误相关的信息,组件栈
作用:错误信息获取,运行副作用
边界错误组件捕获异常,并进行后续处理
在该组件抛出错误后调用
class ErrorBoundary extends React.Component {
state = {
hasError: false,
};
static getDerivedStateFromError(error) {
console.log(1);
return { hasError: true };
}
componentDidCatch(error, info) {
console.log(2);
console.log(otherParams);
console.log(error, info);
}
render() {
if (this.state.hasError) {
return <h1>hasError</h1>;
}
return this.props.children;
}
}
class MyError extends React.Component {
state = {
hasError: false,
};
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
console.log(error, info);
}
render() {
if (this.state.hasError) {
return <h1>My-Error</h1>;
}
return this.props.children;
}
}
class Test extends React.Component {
render() {
// const data = {
// title: 9999,
// };
return <div>{data.title}</div>;
}
}
class Sub extends React.Component {
render() {
return <div>sub content</div>;
}
}
class App extends React.Component {
render() {
return (
<div>
<MyError>
<ErrorBoundary>
<Test />
</ErrorBoundary>
</MyError>
<Sub />
</div>
);
}
}
ReactDOM.render(<App />, document.querySelector("#app"));