写点什么

React Suspense 尝鲜, 处理前后端 IO 异步操作

  • 2022 年 6 月 16 日
  • 本文字数:1726 字

    阅读完需:约 6 分钟

React Suspense 尝鲜,处理前后端IO异步操作

简单介绍一下 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 之前的做法:在 React18 之前,我们要实现上面这个效果,请求数据或者加载新的组件的时机一般在 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.lazyReact.lazy() 允许你定义一个动态加载的组件。这有助于缩减 bundle 的体积,并延迟加载在初次渲染时未用到的组件


const SomeComponent = React.lazy(() => import('./SomeComponent'));
复制代码


渲染 lazy 组件依赖该组件渲染树上层的 &lt;React.Suspense&gt; 组件。这是指定加载指示器(loading indicator)的方式。2.React.SuspenseReact.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>)
复制代码


看一下效果:



本文 Demo:https://gcdn.grapecity.com.cn/forum.php?mod=attachment&aid=MjEyNzM4fDI0MzNlYTIyfDE2NTM4OTI4Mzh8MXwxNDc4NTk%3D


了解更多在线 demo:https://demo.grapecity.com.cn/spreadjs/gc-sjs-samples/index.html

发布于: 刚刚阅读数: 4
用户头像

赋能开发者 2020.05.09 加入

西安葡萄城信息技术有限公司是全球领先的软件开发技术和 低代码 平台提供商,以“ 赋能开发者”为使命,致力于通过各类软件开发工具和服务,创新开发模式,提升开发效率,推动软件产业发展,为“数字中国”建设提速

评论

发布
暂无评论
React Suspense 尝鲜,处理前后端IO异步操作_大前端_葡萄城技术团队_InfoQ写作社区