关于javascript:React-Suspense-尝鲜处理前后端IO异步操作

27次阅读

共计 2253 个字符,预计需要花费 6 分钟才能阅读完成。

简略介绍一下 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.lazy
React.lazy() 容许你定义一个动静加载的组件。这有助于缩减 bundle 的体积,并提早加载在首次渲染时未用到的组件

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

渲染 lazy 组件依赖该组件渲染树下层的 \&lt;React.Suspense\&gt; 组件。这是指定加载指示器(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>
)

看一下成果:

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

理解更多在线 demo:https://demo.grapecity.com.cn…

正文完
 0