7

A brief introduction to Suspense

Suspense is mainly used to solve network IO problems, and it was released as early as 2018 in the React 16.6.0 version. Some of its related usages are relatively mature, and some are relatively unstable, and have even undergone renaming and deletion:

  • In the render function, we can write an asynchronous request to request data
  • react will read this cache from our cache
  • If there is a cache, go directly to the normal render
  • If there is no cache, then an exception will be thrown, this exception is a promise
  • When the promise is completed (the request data is completed), react will continue to return to the original render (actually re-execute the render), and render the data out.
  • Completely synchronous writing, no such thing as asynchronous callbacks

If you don't understand what this means, I can simply state it as follows:

 调用render函数->发现有异步请求->悬停,等待异步请求结果->再渲染展示数据

It's very magical to look at, writing asynchronous with synchronous methods, and there is no yield/async/await, it can make people dumbfounded. The advantage of doing this is that our thinking logic is very simple and clear, there is no callback, and there is no other stuff. I can't help but say that it seems to be very elegant and awesome.

Main usage and scenarios of Suspense

In front-end development, there is often such a demand. When loading an interface, if the resources of the interface are relatively large, the front-end processing of data also takes time, and the loading is relatively slow. At this time, we need to use a loading animation or prompt to make The interaction is more friendly.

1. The practice before React18:
Before React18, we wanted to achieve the above effect. The time to request data or load a new component was generally componentDidMount. In State, a flag variable was needed to record the state of the requested data. It was very inconvenient to manually change this state later. code show as below:

 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} />
    );
  }
}

2. After React18:
1. React.lazy
React.lazy() allows you to define a dynamically loaded component. This helps to reduce the size of the bundle and lazy load components that are not used on the first render

 const SomeComponent = React.lazy(() => import('./SomeComponent'));

Rendering lazy components depends on the \&lt;React.Suspense\&gt; components higher up in the component's render tree. This is how the loading indicator is specified.
2. React. Suspense
React.Suspense can specify a loading indicator in case some child components in its component tree are not yet ready to render:

 // 该组件是动态加载的
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    // 显示 <Spinner> 组件直至 OtherComponent 加载完成
    <React.Suspense fallback={<Spinner />}>
      <div>
        <OtherComponent />
      </div>
    </React.Suspense> 
  );
}

Suspense early adopters: cooperate with front-end table components to handle front-end and back-end IO asynchronous operations

Because there is no back-end logic, the front-end table component is mainly used for online editing and display of Excel and Grid table data in the front-end. Using the technical characteristics of Suspense, the front-end and back-end IO asynchronous operations can be easily realized:

 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>
)

Take a look at the effect:

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

Learn more about online demo: https://demo.grapecity.com.cn/spreadjs/gc-sjs-samples/index.html


葡萄城技术团队
2.7k 声望29.2k 粉丝

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务,一站式满足开发者需求,帮助企业提升开发效率并创新开发模式。