使用 React-Async 库获取声明式数据

介绍

在 JavaScript 应用程序中获取数据时,async-await允许我们使用 imperative synchronous 编程来获取数据,这意味着我们的代码必然会描述该程序将如何运作,并将沿单个操作线程运作。反过来,React 是一个构建 UI 的图书馆 declaratively. 这通常被认为是对立于 imperative 编程的方法,其中开发人员描述了他们希望该程序做什么,而不是他们希望它如何行为。

React-async提供了一个宣言 API,用于使用单个 React 组件执行任何 REST API 调用,允许在整个应用程序中使用宣言编程。

在本文中,我们将解释React-Async库如何帮助我们获取数据,并通过一些辅助组件和函数演示。

通过 React-Async 宣称性地检索数据

让我们把我们的主题分成两个部分:在React中采集声明数据和Asynchronous API Calls。

声明数据采集是一种用于调用API的方法,您声明您希望它为您做什么,而不必担心与呼叫相关的所有事情。

由于 JavaScript 是 同步的默认 和单线程,当我们想要渲染一个组件,显示一些来自以前版本的 React 的非同步呼叫的数据时,需要使用类。

非同步请求将等待请求响应,而代码的其余部分将继续执行。

让我们通过调用终端来证明这一点,以获取货币价格列表:

 1import React, { Component } from 'react';
 2import axios from 'axios';
 3
 4class App extends Component {
 5  state = {
 6    data: [],
 7    error: '',
 8  };
 9
10  componentDidMount() {     
11    axios
12      .get('https://api.coinmarketcap.com/v1/ticker/?limit=1')
13      .then(res => this.setState({ data: res.data }))
14      .catch(error => this.setState({ error }));
15  }
16
17  render () {
18    return (
19      <div className="App">
20        <ul>
21          {this.state.data.map(el => (
22            <li>
23              {el.name}: {el.price_usd}
24            </li>
25          ))}
26        </ul>
27      </div>
28    );
29  }
30}
31
32export default App;

<$>[注] **注:**通过在您的终端中键入npm install axios来安装 axios。

您可以使用 此 CodeSandbox 页面实时查看此代码。

在这里,我们在 **componentDidMount ** 函数中进行 API 调用,以确保该组件在加载后立即运行。

  • 首先,我们向 API 提出请求
  • 然后我们收到响应
  • 我们从响应中提取数据
  • 最后,我们将数据存储在我们的本地状态

在数据采集过程中出现错误的情况下:

  • 我们抓住了错误
  • 然后我们将数据存储在我们的本地状态

在这里,我们明确地描述了如何以及如何在获取数据的每个步骤中做什么。尽管语法和函数正常工作,但代码可以重写以更高效且以更少的行写。

首先,您需要通过在您的终端中键入npm install react-async来安装该包,然后用以下代码写下您的组件:

 1import React, { Component } from 'react';
 2import Async from 'react-async';
 3
 4const loadJson = () =>
 5  fetch("https://api.coinmarketcap.com/v1/ticker/?limit=1")
 6    .then(res => (res.ok ? res : Promise.reject(res)))
 7    .then(res => res.json())
 8
 9const App = () => (
10  <Async promiseFn={loadJson}>
11    {({ data, error, isLoading }) => {
12      if (isLoading) return "Loading..."
13      if (error) return ``Something went wrong: ${error.message}``
14
15      if (data)
16        return (
17          <div>
18             {data.map(el => (
19              <li>
20                {el.name}: {el.price_usd}
21              </li>
22             ))}
23          </div>
24        )
25
26      return null
27    }}
28  </Async>
29)
30
31export default App;

如果您正在使用 CodeSandbox,请从依赖菜单中添加 React-Async。

在这里,我们使用而不是类重写了我们的组件,我们首先创建一个函数loadJson来处理我们的数据采集,然后,在我们的应用程序组件中,我们使用通过 React-Async库提供的Async组件。

一旦我们的承诺得到解决,我们将获得奖励,以处理不同的场景。

  • `isLoading' 可供使用,以便在数据尚未加载时显示易于使用的信息
  • `error' 可用于收集过程中出现错误
  • `data' 是收集完成后返回的实际数据

在此示例中,我们不再需要使用类或生命周期方法来加载我们的数据,也不需要告诉React-Async如何处理数据或如何更新我们的状态。

React-Async 通过 isLoading 落后插头来管理加载状态,该插件会进行渲染,直到 data 准备好渲染,也就是说,当依赖的非同步调用解决并返回数据时。

辅助组件

React-Async 配备了多种 辅助组件,使您的 JSX 更具声明性,更不混乱。每个辅助组件只会在适当的情况下呈现其子女。

 1const App = () => (
 2  <Async promiseFn={loadJson}>
 3    <Async.Loading>Loading...</Async.Loading>
 4
 5    <Async.Resolved>
 6      {data => (
 7        <div>           
 8    	  {data.map(el => (
 9            <li>
10              {el.name}: {el.price_usd}
11            </li>
12          ))}
13        </div>
14      )}
15    </Async.Resolved>
16
17    <Async.Rejected>
18      {error => `Something went wrong: ${error.message}`}
19    </Async.Rejected>
20  </Async>
21)

看看这个例子在 CodeSandbox上。

在本示例中,我们使用了Async.Loading,Async.ResolvedAsync.Rejected函数来简化我们的代码,使其更易于读取。

用户配置文件测试应用程序与辅助功能

让我们构建一个小型用户配置文件应用程序,该应用程序使用一些更多的辅助功能. 更新您的组件到以下代码:

 1import React, { Component } from 'react';
 2import Async from 'react-async';
 3
 4const loadUser = ({ userId }) =>
 5  fetch('`https://reqres.in/api/users/${userId}'`)
 6    .then(res => (res.ok ? res : Promise.reject(res)))
 7    .then(res => res.json())
 8
 9const UserPlaceholder = () => (
10  <div>
11    <div>User Details Loading</div>
12  </div>
13)
14
15const UserDetails = ({ data }) => (
16  <div className="details">
17    <img className="avatar" src={data.data.avatar} alt="" />
18    <div>
19      {data.data.first_name} {data.data.last_name}
20    </div>
21  </div>
22)
23
24const App = () => (
25    <Async promiseFn={loadUser} userId={1}>
26      <Async.Pending>
27        <UserPlaceholder />
28      </Async.Pending>
29      <Async.Fulfilled>{data => <UserDetails data={data} />}</Async.Fulfilled>
30      <Async.Rejected>{error => <p>{error.message}</p>}</Async.Rejected>
31    </Async>
32)
33export default App;

这是 CodeSandbox 的代码.

让我们来谈谈我们宣布的功能:

  • loadUser:我们定义了此函数来处理数据采集. 它采取了 prop (userId) 并根据 id
  • userPlaceholder 查询 API: 这是当承诺尚未解决时显示的 fallback 组件,即当数据尚未完成加载时
  • userDetails: 该组件处理用户数据的实际显示。

结论

在本教程中,我们探索了如何使用 React-Async 库来帮助我们宣告性地获取数据。我们还查看了它提供的一些辅助功能。 有关 React-Async 的更多信息,请参阅 GitHub 上的 React-Async 文档

Published At
Categories with 技术
comments powered by Disqus