30天入坑React ---------------day16 Remote Data

30天入坑React ---------------day16 Remote Data

30天入坑React ---------------day16 Remote Data

这篇文章是30天React系列的一部分 。

在本系列中,我们将从非常基础开始,逐步了解您需要了解的所有内容,以便开始使用React。如果您曾经想学习React,那么这里就是您的最佳选择!

下载免费的PDF

30天入坑React ---------------day16 Remote Data

显示远程数据

用到Promise    注意函数绑定

在Github上编辑此页面

我们的前端应用程序与我们在其中显示的数据一样有趣。今天,我们实际上开始提出数据请求并将其集成到我们的应用程序中。

截至今天,我们已经通过promises,使用npm打包器构建我们的应用程序,安装了我们的远程对象获取库(whatwg-fetch),我们终于准备好将远程数据集成到我们的应用程序中。

获取数据

让我们开始使用fetch我们在第14天安装的库。

为简单起见,让我们从昨天开始我们的演示,我们从API服务器获取当前时间:

30天入坑React ---------------day16 Remote Data

获取当前时间

太平洋标准时间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美东时间世界标准时间

我们将提出以下要求:

30天入坑React ---------------day16 Remote Data

30天入坑React ---------------day16 Remote Data

获取数据

正如我们昨天所说,我们将使用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对象,然后通过将响应值设置dateStringcurrentTime组件状态来更新我们的组件:

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);
  }

// ...
}

最后,当用户提交表单(点击按钮按输入字段中输入)时,我们将要再次提出请求。这意味着我们可以定义我们的handleFormSubmitprop来调用fetchCurrentTime()方法:

class App extends React.Component {

// ...
  handleFormSubmit(evt) {
    this.fetchCurrentTime();
  }

// ...
}

30天入坑React ---------------day16 Remote Data

当前时间是:2018-10-22 22:04:46 -07:00

太平洋标准时间MSTMDT美东时间世界标准时间

我们将提出以下要求: https://andthetimeis.com/PST/now.json

尝试使用演示并传递不同的慢性选项。这真的很有趣。

无论如何,今天我们花了很多时间将远程数据导入我们的应用程序。但是,此时,我们的单页应用中只有一个页面。如果我们想在我们的应用中显示不同的页面怎么办?明天,我们将开始在我们的应用中添加多个页面,以便我们可以显示不同的视图。

30天入坑React ---------------day16 Remote Data

学习REACT正确的方法

React和朋友的最新,深入,完整的指南。

下载第一章

❮上一个

下一章:

客户端路由

下一个 ❯

本教程系列的完整源代码可以在GitHub repo找到,其中包括所有样式和代码示例。

如果您在任何时候感到困难,还有其他问题,请随时通过以下方式与我们联系: