简单介绍一下Suspense
Suspense主要用于解决网络问题IO问题,早在2018年,React 16.6.0版本已经发布。其中一些相关用法相对成熟,有些相对不稳定,甚至经历了重命名和删除:
- 在render在函数中,我们可以写一个异步请求,请求数据
- react这个缓存将从我们的缓存中读取
- 如有缓存,直接正常render
- 如果没有缓存,就会抛出异常,这是一个异常promise
- 当这个promise完成后(完成请求数据),react会继续回到原来的render中(其实是重新执行的render),把数据render出来
- 完全同步写法,无异步写法callback之类的东西
如果你还不明白这是什么意思,那我就简单地说下面这句话:
调用render函数->发现异步请求->悬停,等待异步请求结果->再次渲染显示数据
看起来很神奇,用同步法写异步,没有yield/async/await,能让人目瞪口呆。这样做的好处自然是我们的思维逻辑很简单,清晰,没有callback,没有别的东西,不得不说,看似优雅又牛逼。
Suspense 主要用法和场景
在前端开发中,经常会有这样的需求。在加载界面时,如果界面资源相对较大,前端也需要时间处理数据,加载速度相对较慢。此时,我们需要使用加载动画或提示来使交互更加友好。
一. React18之前的做法: 在React在18岁之前,我们需要实现上述效果,请求数据或加载新组件的时间通常是componentDidMount,在State中需要一个flag变量记录请求数据的状态,手动更改后续状态,非常不方便。代码如下:
class App extends Component { state = { isLoading: false, } componentDidMount() { this.setState({ data: null, isLoading: true, }); axios.get('/api/getData').then((data) => { this.setState({ data, isLoading: false, }); }); } render() { return this.state.loading ? 正在加载...' : ( <Page data={data} /> ); } }
二. React18之后: 1.React.lazy React.lazy() 允许你定义一个动态加载的组件。这有助于缩减 bundle 第一次渲染时未使用的组件的体积延迟加载
const SomeComponent = React.lazy(() => import('./SomeComponent'));
渲染 lazy 组件依赖于组件渲染树上层 <React.Suspense> 组件。指定加载指示器(loading indicator)的方式。 2.React.Suspense React.Suspense 可指定加载指示器(loading indicator),防止其组件树中的某些子组件不具备渲染条件:
// 动态加载组件 const OtherComponent = React.lazy(() => import('./OtherComponent')); function MyComponent() { return ( // 显示 <Spinner> 组件直至 OtherComponent 加载完成 <React.Suspense fallback={<Spinner />}> <div> <OtherComponent /> </div> </React.Suspense> ); }
Suspense尝鲜:用前端表组件处理前后端IO异步操作
由于没有后端逻辑,前端表单组件主要用于前端对齐 Excel、Grid 在线编辑和显示表格数据Suspense前后端的技术特点很容易实现IO异步操作:
const PureSpread = React.lazy(() => import('./components/pureSpread')) const SpreadDesigner = React.lazy(() => import('./components/designer')) const {Content,Header} = Layout const App = () => ( <Layout className="app"> <IndexSider/> <Layout> <Content className="index-content"> <HashRouter> <Switch> <Suspense fallback={<div>loading...</div>}> <Route exact path="/" component={PureSpread}/> <Route exact path="/designer" component={SpreadDesigner}/> </Suspense> </Switch> </HashRouter> </Content> <IndexFooter/> </Layout> </Layout> )
看效果: [外链图片转存失败,源站可能有防盗链机制,建议保存图片并直接上传(img-HrHNtcG0-1655358574521)(https://img2022.cnblogs.com/blog/139239/202206/139239-20220616134450724-1802491738.png)]
本文Demo:https://gcdn.grapecity.com.cn/forum.php?mod=attachment&aid=MjEyNzM4fDI0MzNlYTIyfDE2NTM4OTI4Mzh8MXwxNDc4NTk=
了解更多在线信息demo:https://demo.grapecity.com.cn/spreadjs/gc-sjs-samples/index.html