React 中的 Suspense and lazy 使用介绍
Suspense 作用
Suspense 的中文意思是悬而不定,顾名思义指的是数据加载完成之前页面呈现的内容。
在 Suspense 内的任何子组件(数据)只要还在 pending 或者初始状态,则显示的是 fallback 的内容。等所有的数据加载完成才显示子组件,避免多次更新。
此功能与传统的数据渲染前用一个 loading 状态过度很像,只不过 React 提供了 Suspense 组件来更优雅地处理渲染前的显示问题。
lazy 作用
我们都知道使用 webpack 打包后会将所有的资源打包到一个入口文件中,这样可以减少请求的资源数量。
当然我们可以使用 mini-css-extract-plugin 插件将 CSS 单独分割出来。但是所有的项目打包到一个 js 文件难免造成体积过大加载缓慢的情况。
使用 React.lazy 可以将组件打包到单独的 chunk 文件中,并且实现按需加载。比如在加载首页时只加载首页所需要的资源文件,这样就可以提升加载速度。
React.lazy 是一个函数,需要动态调用 import()。它必须返回一个 Promise,该 Promise 需要 resolve 一个 defalut export 的 React 组件。
如果不使用 lazy,你是这样引入组件:
import App from './App';
使用 lazy 之后,就是这样引入组件:
const App = React.lazy(() => import('./App.js'));
通常 lazy 与 Suspense 组件配合使用,这样在懒加载过程中可以呈现友好的等待界面,如 loading 图等。
Suspense 与 lazy 结合使用案例
以下 Suspense 组件内提供三个子组件。
一个是 Promise 的异步组件;
一个是 需要更新的 state 数据;
一个是 lazy 懒加载的组件。
在三个组件全部加载完成前显示的是 fallback 的内容。
全部加载完成后才将组件内容显示出来。
index.js
import React,{
Suspense,lazy} from 'react';
const LazyComp = lazy(()=>import('./lazy.js'));
let data = "";
let promise = "";
function requestData() {
if(data){
return data;
}
if(promise){
throw promise}
promise = new Promise((resolve)=>{
setTimeout(()=>{
data = "数据出来了";
resolve();
},2000)
})
throw promise
}
function SuspenseComp() {
const data = requestData();
return <p>{
data}</p>
}
export default class CommonTable extends React.Component{
constructor(){
super();
this.state={
title:"初始标题"
}
}
componentDidMount(){
this.setState({
title:"渲染后的标题"
})
}
render(){
return<Suspense fallback="loading">
<SuspenseComp/>
<div>{
this.state.title}</div>
<LazyComp/>
</Suspense>
}
}
lazy.js
import React from 'react';
export default ()=><p>lazy data</p>
初始时效果:
2s 后全部加载完成效果: