这篇文章是30天React系列的一部分 。
在本系列中,我们将从非常基础开始,逐步了解您需要了解的所有内容,以便开始使用React。如果您曾经想学习React,那么这里就是您的最佳选择!
显示远程数据
用到Promise 注意函数绑定
我们的前端应用程序与我们在其中显示的数据一样有趣。今天,我们实际上开始提出数据请求并将其集成到我们的应用程序中。
截至今天,我们已经通过promises,使用npm
打包器构建我们的应用程序,安装了我们的远程对象获取库(whatwg-fetch
),我们终于准备好将远程数据集成到我们的应用程序中。
获取数据
让我们开始使用fetch
我们在第14天安装的库。
为简单起见,让我们从昨天开始我们的演示,我们从API服务器获取当前时间:
获取当前时间
太平洋标准时间MSTMDT美东时间世界标准时间
我们将提出以下要求:
此演示反应组件向API服务器发出请求,并从其时钟报告当前时间。在我们将调用添加到fetch之前,让我们创建一些有状态的组件,我们将用它来显示时间并更新时间请求。
墙壁的代码警告
我们意识到接下来的几行代码是我们通常试图避免的代码,特别是在没有讨论它们是如何工作的情况下。但是,由于我们不是在讨论如何在此详细创建组件,但我们仍然希望填写完整的组件,我们已经例外了。
如果您希望我们今天更改此方法,请留下反馈(底部链接)。
首先,将显示和获取当前时间的包装器组件的基础如下所示。让我们将此代码复制并粘贴到我们的应用中src/App.js
:
import React from 'react';
import 'whatwg-fetch';
import './App.css';
import TimeForm from './TimeForm';
class App extends React.Component {
constructor(props) {
super(props);
this.fetchCurrentTime = this.fetchCurrentTime.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
this.state = {
currentTime: null, msg: 'now'
}
}
// methods we'll fill in shortly
fetchCurrentTime() {}
getApiUrl() {}
handleFormSubmit(evt) {}
handleChange(newState) {}
render() {
const {currentTime, tz} = this.state;
const apiUrl = this.getApiUrl();
return (
<div>
{!currentTime &&
<button onClick={this.fetchCurrentTime}>
Get the current time
</button>}
{currentTime && <div>The current time is: {currentTime}</div>}
<TimeForm
onFormSubmit={this.handleFormSubmit}
onFormChange={this.handleChange}
tz={tz}
msg={'now'}
/>
<p>We'll be making a request from: <code>{apiUrl}</code></p>
</div>
)
}
}
export default App;
前面的组件是我们创建的基本状态React组件。由于我们想要显示一个表单,我们已经包含了TimeForm
下一个let的创建用途。
让我们在反应应用程序中使用创建此组件create-react-app
。将文件添加src/TimeForm.js
到我们的项目中:
touch src/TimeForm.js
现在让我们添加内容。我们希望我们TimeForm
扮演允许用户在浏览器中切换时区的角色。我们可以通过创建一个我们称之为的有状态组件来处理这个问题TimeForm
。我们的TimeForm
组件可能如下所示:
import React from 'react'
const timezones = ['PST', 'MST', 'MDT', 'EST', 'UTC']
export class TimeForm extends React.Component {
constructor(props) {
super(props);
this._handleChange = this._handleChange.bind(this);
this._changeTimezone = this._changeTimezone.bind(this);
this._changeMsg = this._changeMsg.bind(this);
this._handleFormSubmit = this._handleFormSubmit.bind(this);
const {tz, msg} = this.props;
this.state = {tz, msg};
}
_handleChange(evt) {
typeof this.props.onFormChange === 'function' &&
this.props.onFormChange(this.state);
}
_changeTimezone(evt) {
const tz = evt.target.value;
this.setState({tz}, this._handleChange);
}
_changeMsg(evt) {
const msg =
encodeURIComponent(evt.target.value).replace(/%20/, '+');
this.setState({msg}, this._handleChange);
}
_handleFormSubmit(evt) {
evt.preventDefault();
typeof this.props.onFormSubmit === 'function' &&
this.props.onFormSubmit(this.state);
}
render() {
const {tz} = this.state;
return (
<form onSubmit={this._handleFormSubmit}>
<select
onChange={this._changeTimezone}
defaultValue={tz}>
{timezones.map(t => {
return (<option key={t} value={t}>{t}</option>)
})}
</select>
<input
type="text"
placeholder="A chronic string message (such as 7 hours from now)"
onChange={this._changeMsg}
/>
<input
type="submit"
value="Update request"
/>
</form>
)
}
}
export default TimeForm;
创建这些组件之后,让我们在运行它之后在浏览器中加载我们的应用程序npm start
,我们将看到我们的表单(尽管还不是非常漂亮)。当然,在这一点上,我们没有运行组件,因为我们还没有实现数据提取。我们现在就谈谈。
获取当前时间
太平洋标准时间MSTMDT美东时间世界标准时间
我们将提出以下要求:
获取数据
正如我们昨天所说,我们将使用fetch()
具有承诺支持的API。当我们调用该fetch()
方法时,它将返回一个promise,我们可以根据需要处理请求。我们将向我们现在的API服务器发出请求(因此如果一段时间没有运行,启动可能会很慢)。
我们将构建我们要求的URL,因为它代表我们将在服务器上请求的时间查询。
我已经getApiUrl()
在App
组件中定义了方法,所以让我们填充该函数。
慢性api服务器接受我们将在表单中自定义的一些变量。这需要时区和慢性信息。我们将简单地开始并向慢性库询问pst
时区和当前时间(now
):
class App extends React.Component {
constructor(props) {
super(props);
this.fetchCurrentTime = this.fetchCurrentTime.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
this.state = {
currentTime: null, msg: 'now', tz: 'PST'
}
}
// ...
getApiUrl() {
const {tz, msg} = this.state;
const host = 'https://andthetimeis.com';
return host + '/' + tz + '/' + msg + '.json';
}
// ...
export default App;
现在,当我们打电话时getApiUrl()
,将为我们返回下一个请求的URL。现在,最后,让我们实现我们的fetch()
功能。该fetch()
函数接受一些可以帮助我们自定义请求的参数。最基本的GET
请求可以只占用一个URL端点。返回值fetch()
是一个承诺对象,我们昨天进行了深入探讨。
让我们更新我们的fetchCurrentTime()
方法以从远程服务器获取当前时间。我们将.json()
在响应对象上使用该方法将响应的主体从JSON对象转换为JavaScript对象,然后通过将响应值设置dateString
为currentTime
组件状态来更新我们的组件:
class App extends React.Component {
// ...
fetchCurrentTime() {
fetch(this.getApiUrl())
.then(resp => resp.json())
.then(resp => {
const currentTime = resp.dateString;
this.setState({currentTime})
})
}
// ...
}
我们今天项目的最后一部分是从表单中获取数据以更新父组件。也就是说,当用户更新TimeForm
组件中的值时,我们希望能够访问App
组件中的数据。该TimeForm
组件已经处理了这个过程我们,所以我们只需要实现表单功能。
当一个状态在表单组件上发生更改时,它将调用一个名为的prop onFormChange
。通过在我们的App
组件中定义此方法,我们可以访问最新版本的表单。
实际上,我们只是打电话setState()
来跟踪表单允许用户操作的选项:
class App extends React.Component {
// ...
handleChange(newState) {
this.setState(newState);
}
// ...
}
最后,当用户提交表单(点击按钮或按输入字段中输入)时,我们将要再次提出请求。这意味着我们可以定义我们的handleFormSubmit
prop来调用fetchCurrentTime()
方法:
class App extends React.Component {
// ...
handleFormSubmit(evt) {
this.fetchCurrentTime();
}
// ...
}
当前时间是:2018-10-22 22:04:46 -07:00
太平洋标准时间MSTMDT美东时间世界标准时间
我们将提出以下要求: https://andthetimeis.com/PST/now.json
尝试使用演示并传递不同的慢性选项。这真的很有趣。
无论如何,今天我们花了很多时间将远程数据导入我们的应用程序。但是,此时,我们的单页应用中只有一个页面。如果我们想在我们的应用中显示不同的页面怎么办?明天,我们将开始在我们的应用中添加多个页面,以便我们可以显示不同的视图。
学习REACT正确的方法
React和朋友的最新,深入,完整的指南。
下一章:
客户端路由
本教程系列的完整源代码可以在GitHub repo上找到,其中包括所有样式和代码示例。
如果您在任何时候感到困难,还有其他问题,请随时通过以下方式与我们联系:
- 在文章末尾评论这篇文章
- 通过react@fullstackreact.com发送电子邮件给我们
- 加入我们的gitter室
- 发送电子邮件至@fullstackreact