在 React 中成功调用 API 时动态更改状态绑定内容
介绍
React 组件渲染内容的元素可以与组件的state属性绑定。每当我们更新state的值时,我们都会自动更新引用其属性的内容。在本指南中,我们将了解如何从第三方 API 获取的数据动态更新组件的渲染内容。
流程如下:
- 在组件的状态内建立对象数据
- 使用引用数据中的属性的部分来建立要呈现的内容
- 创建从 API 获取数据的事件处理程序
- API 调用成功后,更新组件的状态
我们将使用jQuery作为我们的库来针对 API 端点发出 HTTP 请求。
设置
在这个例子中,我们将从CoinDesk 的公共 API中获取最新的比特币价格。我们的内容将包括美元、英镑和欧元对 BTC(比特币)的价格。API 端点https://api.coindesk.com/v1/bpi/currentprice.json返回的数据的 JSON 结构如下:
{
time: {
updated: "Sep 16, 2020 18:43:00 UTC",
updatedISO: "2020-09-16T18:43:00+00:00",
updateduk: "Sep 16, 2020 at 19:43 BST"
},
disclaimer: "This data was produced from the CoinDesk Bitcoin Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org",
chartName: "Bitcoin",
bpi: {
USD: {
code: "USD",
symbol: "$",
rate: "11,091.2212",
description: "United States Dollar",
rate_float: 11091.2212
},
GBP: {
code: "GBP",
symbol: "£",
rate: "8,436.3156",
description: "British Pound Sterling",
rate_float: 8436.3156
},
EUR: {
code: "EUR",
symbol: "€",
rate: "9,395.0075",
description: "Euro",
rate_float: 9395.0075
}
}
}
设置状态
调用您的组件BTCPrice 。在其构造函数中,将属性数据的值设置为具有与 API 端点的预期返回值相同的结构。
import React from 'react';
import $ from 'jquery';
export default class BTCPrice extends React.Component {
constructor(props) {
super(props);
this.state = {
data: {
time: {
updated: "",
updatedISO: "",
updateduk: ""
},
disclaimer: "This data was produced from the CoinDesk Bitcoin Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org",
chartName: "Bitcoin",
bpi: {
USD: {
code: "USD",
symbol: "$",
rate: "",
description: "United States Dollar",
rate_float: 0
},
GBP: {
code: "GBP",
symbol: "£",
rate: "",
description: "British Pound Sterling",
rate_float: 0
},
EUR: {
code: "EUR",
symbol: "€",
rate: "",
description: "Euro",
rate_float: 0
}
}
}
}
}
}
设置渲染内容
组件将渲染引用data中属性的内容,这些属性可从组件的state中依次引用。复制下面的render()函数并将其粘贴到您的组件中。
render() {
return (
<div>
<h1>
How Much is 1 BTC?
<small>
{this.sate.data.time.updated}
</small>
</h1>
<h2>USD: {this.state.data.bpi.USD.rate}</h2>
<h2>GBP: {this.state.data.bpi.GBP.rate}</h2>
<h2>EUR: {this.state.data.bpi.EUR.rate}</h2>
<hr/>
<button>
Fetch Latest
</button>
</div>
);
}
注意我们如何在不同的 HTML dom 元素中定位货币的汇率。将其视为一个模板,其中数据属性的引用是值的占位符,这些值的占位符可能会在组件状态更新时发生变化。我们说这些部分与状态绑定。在这种情况下,我们将引用的数据的属性值代表三种不同的货币及其与比特币的汇率,即:
- this.state.data.bpi.USD.rate美元
- this.state.data.bpi.GBP.rate为 GBP
- this.state.data.bpi.EUR.rate为欧元
我们还引用顶部的data.time.updated值来指示这些价格的时间戳。
从 API 获取数据
我们现在将创建事件处理程序函数,其中包含针对 CoinDesk 的 API 发出 AJAX 请求的逻辑。为此,请复制以下函数并将其粘贴到您的组件中。
fetch() {
var context = this;
$.ajax({
url: 'https://api.coindesk.com/v1/bpi/currentprice.json',
method: 'GET',
dataType: 'json',
success: function(response) {
context.setState({
data: response
});
}
});
}
成功时更新状态
此函数的实现有两个关键思想。首先,创建一个名为context的临时变量,指向引用此组件实例的this 。这是必需的,因为传递给jQuery的 AJAX 调用的success 属性的function(response)给出的 AJAX 调用成功后,您可以从context调用setState({ data: response })调用。如果没有context,function(response)中的this将引用调用函数而不是组件实例。其次,您必须将dataType属性设置为json,因为我们希望response表示API 端点返回的json对象。
一旦调用setState() ,组件将使用状态的所有更新值重新渲染内容。
绑定到按钮
每次用户点击按钮时,都会触发组件的 fetch() 方法。在组件的 render() 方法中更新 HTML 中的按钮,并将fetch() 方法绑定到按钮的onClick属性上。
<button onClick={this.fetch.bind(this)}>
Fetch Latest
</button>
包含.bind(this)函数,以便在fetch()中使用时保留this的值,即对组件实例的引用。
总体代码
import React from 'react';
import $ from 'jquery';
export default class BTCPrice extends React.Component {
constructor(props) {
super(props);
this.state = {
data: {
time: {
updated: "",
updatedISO: "",
updateduk: ""
},
disclaimer: "",
chartName: "",
bpi: {
USD: {
code: "USD",
symbol: "$",
rate: "",
description: "United States Dollar",
rate_float: 0
},
GBP: {
code: "GBP",
symbol: "£",
rate: "",
description: "British Pound Sterling",
rate_float: 0
},
EUR: {
code: "EUR",
symbol: "€",
rate: "",
description: "Euro",
rate_float: 0
}
}
}
}
}
fetch() {
var context = this;
$.ajax({
url: 'https://api.coindesk.com/v1/bpi/currentprice.json',
method: 'GET',
dataType: 'json',
success: function(re
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~