react async_使用React-Async库进行声明式数据获取

本文介绍了React-Async库如何帮助在React应用中以声明式方式获取数据。React-Async提供声明式API,处理错误、承诺解析和重试,保持应用的声明式编程风格。文章通过示例展示了如何避免使用类和生命周期方法,而是利用React-Async简化异步数据获取,以及如何利用其辅助组件来提升代码的可读性和简洁性。
摘要由CSDN通过智能技术生成

react async

介绍 (Introduction)

When fetching data in a JavaScript application, async-await allows us to use imperative synchronous programming for fetching data. This means that our code will imperatively describe how the program will function and will operate along a single thread of operations. React, on the other hand, is a library that build UIs declaratively. This is often considered to be an opposing method to imperative programming, in which the developer describes what they want the program to do, rather than how they want it to behave. The combination of React and async-await therefore leads to a mixed pattern in which we have both imperative code (for data fetching) and declarative code (for UI composition).

在JavaScript应用程序中获取数据时, async-await允许我们使用命令式同步编程来获取数据。 这意味着我们的代码将强制性地描述程序如何运行以及如何沿着单个操作线程运行。 另一方面,React是一个以声明方式构建UI的库。 通常将其视为命令式编程的一种相反方法,在该方法中,开发人员描述他们希望程序执行的操作,而不是他们希望程序如何执行。 因此,React和async-await的组合导致了一种混合模式,在该模式中,我们同时具有命令性代码(用于数据提取)和声明性代码(用于UI组合)。

React-async provides a declarative API to perform any REST API calls using a single React component, allowing declarative programming to be used throughout the application. It takes care of handling errors, promise resolution, and retrying promises, and deals with local asynchronous state.

React-async提供了一个声明式API,以使用单个React组件执行任何REST API调用,从而允许在整个应用程序中使用声明式编程。 它负责处理错误,承诺解析和重试承诺,并处理本地异步状态。

In this article, we will explain how the React-Async library helps us fetch data and run through some demonstrations of Helper components and functions.

在本文中,我们将解释React-Async库如何帮助我们获取数据并通过一些Helper组件和功能的演示来运行。

使用React-Async声明式获取数据 (Fetching Data Declaratively with React-Async)

Let’s break down our topic into two parts: Declarative data fetching and Asynchronous API Calls in React.

让我们将主题分为两部分: 声明式数据获取和React中的异步API调用

Declarative data fetching is an approach used in calling APIs in which you declare what you want it to do for you without you worrying about all the things related to the call. It’s the opposite of the imperative approach where you also need to detail the steps you want the program to take.

声明式数据获取是一种用于调用API的方法,通过该方法,您可以声明要为您执行的操作,而不必担心与调用有关的所有事情。 这与命令式方法相反,在命令式方法中,您还需要详细说明希望程序执行的步骤。

Since JavaScript is synchronous by default and is single threaded, when we want to render a component that shows some data coming from an asynchronous call in previous versions of React, classes needed to be used. We had to use the component lifecycle methods to ensure the call happened when the component was mounted, and then we used the local state to manage the loading state.

由于JavaScript 默认情况下同步的并且是单线程的,因此当我们想要渲染一个组件,该组件显示一些来自React早期版本中异步调用的数据时,需要使用类。 我们必须使用组件生命周期方法来确保调用在安装组件时发生,然后我们使用本地状态来管理加载状态。

Asynchronous requests will wait for a request to respond while the rest of the code continues to execute. Then when the time is right, a callback will spring these asynchronous requests into action.

异步请求将等待请求响应,而其余代码将继续执行。 然后,当时间合适时,回调将使这些异步请求生效。

Let’s demonstrate this by making a call to an endpoint to grab a list of currency prices:

让我们通过调用一个端点以获取货币价格列表来演示这一点:

import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {
  state = {
    data: [],
    error: '',
  };

  componentDidMount() {     
    axios
      .get('https://api.coinmarketcap.com/v1/ticker/?limit=1')
      .then(res => this.setState({ data: res.data }))
      .catch(error => this.setState({ error }));
  }

  render () {
    return (
      <div className="App">
        <ul>
          {this.state.data.map(el => (
            <li>
              {el.name}: {el.price_usd}
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

export default App;

Note: Install axios by typing ‘npm install axios` into your terminal.

注意:在终端中输入“ npm install axios”来安装axios。

You can see this code live using this CodeSandbox page.

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

Here we make our API call in the componentDidMount function to ensure it runs as soon as the component is loaded. We can make sense of our data only after we go through the following steps:

在这里,我们在componentDidMount函数中进行API调用,以确保它在组件加载后立即运行。 只有经过以下步骤,我们才能理解我们的数据:

  • First, we make a request to the API.

    首先,我们向API发出请求。
  • We then receive a response.

    然后,我们会收到回复。
  • We extract data from the response.

    我们从响应中提取数据。
  • Finally, we store the data in our local state.

    最后,我们将数据存储在本地状态。

In the event of an error during the data fetching process:

在数据获取过程中发生错误时:

  • We catch the error.

    我们抓住了错误。
  • We then store the data in our local state.

    然后,我们将数据存储在本地状态。

Here we are explicitly describing how and what to do at every step in fetching the data. Though the syntax and functions work correctly, the code can be re-written to be more efficient and in fewer lines if written declaratively. Let’s rewrite it using React-Async.

在这里,我们明确描述了在获取数据的每个步骤中如何做和做什么。 尽管语法和功能可以正常工作,但是如果以声明方式编写,则可以重新编写代码,以提高效率,并减少行数。 让我们使用React-Async重写它。

First, you need to install the package by typing npm install react-async in your terminal. Then write your component with the following code:

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

import React, { Component } from 'react';
import Async from 'react-async';

const loadJson = () =>
  fetch("https://api.coinmarketcap.com/v1/ticker/?limit=1")
    .then(res => (res.ok ? res : Promise.reject(res)))
    .then(res => res.json())

const App = () => (
  <Async promiseFn={loadJson}>
    {({ data, error, isLoading }) => {
      if (isLoading) return "Loading..."
      if (error) return ``Something went wrong: ${error.message}``

      if (data)
        return (
          <div>
             {data.map(el => (
              <li>
                {el.name}: {el.price_usd}
              </li>
             ))}
          </div>
        )

      return null
    }}
  </Async>
)

export default App;

If you are using CodeSandbox, add React-Async from the dependency menu. If you’d like to see this code live, take a look at the React-Async example in CodeSandbox.

如果您使用的是CodeSandbox,请从依赖项菜单中添加React-Async。 如果您想实时观看此代码,请查看CodeSandbox中的React-Async示例

Here we have rewritten our component using hooks instead of classes. We first create a function loadJson to handle our data fetching. Then, inside our App component, we utilize the Async component made available through the React-Async library.

在这里,我们使用钩子而不是类重写了组件。 我们首先创建一个loadJson函数来处理数据获取。 然后,在我们的App组件内部,我们利用可通过React-Async库使用的Async组件。

Once our promise is resolved, props are made available to us to handle different scenarios.

一旦我们的诺言得以兑现,我们就可以使用各种道具来处理不同的情况。

  • isLoading is available so we can display a user-friendly message while the data is yet to be loaded.

    isLoading可用,因此我们可以在尚未加载数据时显示一条用户友好的消息。

  • error is available in case of an error during the fetch.

    如果在提取期间error则可以使用error。

  • data is the actual data returned after the fetching is complete.

    data是提取完成后返回的实际数据。

In this example, we no longer have to use classes or lifecycle methods to load our data, nor do we need to tell React-Async how to process the data or how to update our state.

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

React-Async manages the loading state through the isLoading fallback prop, which is rendered until data is ready to be rendered, that is, when the dependent asynchronous call resolves and returns the data.

React-Async通过isLoading fallback isLoading管理加载状态,该isLoading会一直呈现直到准备好呈现data为止,也就是说,当相关的异步调用解析并返回数据时。

辅助组件 (Helper Components)

React-Async comes with several helper components that make your JSX more declarative and less cluttered. Each of the helper components will only render its children when appropriate. We can rewrite our App function to look like this:

React-Async带有几个帮助程序组件 ,这些组件使您的JSX更具声明性,并且更加混乱。 每个帮助程序组件仅在适当时才渲染其子级。 我们可以将App函数重写如下:

const App = () => (
  <Async promiseFn={loadJson}>
    <Async.Loading>Loading...</Async.Loading>

    <Async.Resolved>
      {data => (
        <div>           
          {data.map(el => (
            <li>
              {el.name}: {el.price_usd}
            </li>
          ))}
        </div>
      )}
    </Async.Resolved>

    <Async.Rejected>
      {error => `Something went wrong: ${error.message}`}
    </Async.Rejected>
  </Async>
)

Check out this example on CodeSandbox.

CodeSandbox上查看此示例。

In this example, we have used the Async.Loading, Async.Resolved, and Async.Rejected functions to simplify our code and make it more readable. Helper components provided by React-Async can take a React element or a function as children. When you provide a function, you’ll receive render props you can use in your component.

在此示例中,我们使用了Async.LoadingAsync.ResolvedAsync.Rejected函数来简化代码并使代码更具可读性。 React-Async提供的帮助器组件可以将React元素或函数作为子元素。 提供功能时,您会收到可在组件中使用的渲染道具。

具有帮助功能的用户配置文件测试应用 (User Profile Test App with Helper Functions)

Let’s build a small user profile app that uses some more helper functions. Update your component to the following code:

让我们构建一个使用更多辅助功能的小型用户配置文件应用程序。 将组件更新为以下代码:

import React, { Component } from 'react';
import Async from 'react-async';

const loadUser = ({ userId }) =>
  fetch('`https://reqres.in/api/users/${userId}'`)
    .then(res => (res.ok ? res : Promise.reject(res)))
    .then(res => res.json())

const UserPlaceholder = () => (
  <div>
    <div>User Details Loading</div>
  </div>
)

const UserDetails = ({ data }) => (
  <div className="details">
    <img className="avatar" src={data.data.avatar} alt="" />
    <div>
      {data.data.first_name} {data.data.last_name}
    </div>
  </div>
)

const App = () => (
    <Async promiseFn={loadUser} userId={1}>
      <Async.Pending>
        <UserPlaceholder />
      </Async.Pending>
      <Async.Fulfilled>{data => <UserDetails data={data} />}</Async.Fulfilled>
      <Async.Rejected>{error => <p>{error.message}</p>}</Async.Rejected>
    </Async>
)
export default App;

This is the code in CodeSandbox.

这是CodeSandbox中的代码。

Let’s go over the functions we declared:

让我们看一下我们声明的函数:

  • loadUser: We define this function to handle data fetching. It takes in a prop (userId) and queries the API based on the id.

    loadUser :我们定义此函数来处理数据提取。 它接受一个prop( userId )并根据id查询API。

  • userPlaceholder: This is the fallback component that will be displayed when the promise has not yet resolved, that is, when the data has not finished loading.

    userPlaceholder :这是回退组件,将在承诺尚未解决(即数据尚未完成加载)时显示。

  • userDetails: This component handles the actual display of the user data. It takes the data in via props and is only rendered when the promise has been resolved.

    userDetails :该组件处理用户数据的实际显示。 它通过道具接收数据,并且仅在诺言已解决时才呈现。

  • Async.Pending,Async.Fulfilled, and Async.Rejected: These are functions to simplify our code and make it more readable.

    Async.PendingAsync.FulfilledAsync.Rejected :这些功能可以简化我们的代码并使其更具可读性。

结论 (Conclusion)

In this tutorial, we explored how to use the React-Async library to help us fetch data declaratively. We also looked at some of the helper functions it offers. To learn more about React-Async, check out the React-Async docs on GitHub.

在本教程中,我们探索了如何使用React-Async库来帮助我们声明式获取数据。 我们还研究了它提供的一些帮助器功能。 要了解有关React-Async的更多信息,请查看GitHub上React-Async文档

翻译自: https://www.digitalocean.com/community/tutorials/using-the-react-async-library-for-declarative-data-fetching

react async

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值