【全栈React】第16天: 显示远程数据

本文转载自:众成翻译
译者:iOSDevLog
连接:http://www.zcfy.cc/article/3813
原文:https://www.fullstackreact.com/30-days-of-react/day-16/javascript

咱们的前端应用与咱们在其中显示的数据同样有趣。今天,咱们开始提出数据请求,并将其集成到咱们的应用中。css

截至今天, 咱们已经经过承诺, 使用 npm包创建咱们的应用程序, 安装咱们的远程对象获取库 (whatwg-fetch), 咱们终于准备好将远程数据集成到咱们的应用程序中。前端

获取数据

咱们安装在 第14 天fetch 库后让咱们进入使用它。java

为了简单起见, 让咱们从昨天从 api 服务器获取当前时间的示例中进行演示:react

此演示反应组件对 api 服务器发出请求, 并从它的时钟中报告当前时间。在咱们添加调用来获取以前, 让咱们建立一些有状态的组件, 咱们将用来显示时间并更新时间请求。ajax

代码警告墙

咱们意识到, 接下来的几行是 _代码警告墙_, 咱们一般试图避免, 特别是没有讨论如何工做。然而, 因为咱们不是在讨论如何在这里详细地建立一个组件, 可是咱们仍是要填写一个完整的组件, 咱们已经破例了。npm

若是你但愿咱们改变今天的作法,请留下咱们的反馈 (底部的连接),。json

首先, 将显示和获取当前时间的包装组件的基础以下所示。让咱们复制并粘贴到咱们的应用程序在src/App.js的代码:api

import React from 'react';
import 'whatwg-fetch';
import './App.css';
import TimeForm from './TimeForm';

class App extends React.Component {
  constructor(props) {
    super(props);
    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.bind(this)}>
            Get the current time
          </button>}
        {currentTime && <div>The current time is: {currentTime}</div>}
        <TimeForm
          onFormSubmit={this.handleFormSubmit.bind(this)}
          onFormChange={this.handleChange.bind(this)}
          tz={tz}
          msg={'now'}
        />
        <p>We'll be making a request from: <code>{apiUrl}</code></p>
      </div>
    )
  }
}

export default App;

前面的组件是咱们建立的基本状态响应组件。由于咱们要显示一个表单, 咱们已经包括了 TimeForm 的预期用法, 让咱们建立下一个。浏览器

让咱们在咱们的反应应用程序中使用 create-react-app. 来建立这个组件。将文件src/TimeForm.js 添加到咱们的项目中:

touch src/TimeForm.js

如今, 让咱们添加内容。咱们但愿咱们的 TimeForm t可以发挥做用, 容许用户在浏览器中切换时区。咱们能够经过建立一个 stateful 组件来处理这个, 咱们称之为 TimeForm。咱们的TimeForm组件的外观可能以下所示:

import React from 'react'
const timezones = ['PST', 'MST', 'MDT', 'EST', 'UTC']

export class TimeForm extends React.Component {
  constructor(props) {
    super(props);

    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.bind(this)}>
        <select
          onChange={this._changeTimezone.bind(this)}
          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.bind(this)}
        />
        <input
          type="submit"
          value="Update request"
        />
      </form>
    )
  }
}

export default TimeForm;

随着这些组件的建立, 让咱们在浏览器中加载咱们的应用程序后, npm start 后运行 , 咱们将看到咱们的形式 (虽然尚未使人难以置信的美丽)。固然, 在这一点上, 咱们不会有一个正在运行的组件, 由于咱们没有实现咱们的数据获取。让咱们如今就开始吧。

获取数据

正如咱们昨天所说的, 咱们将使用fetch() api 和承诺支持。当咱们调用fetch() 的方法, 它会返回咱们的承诺, 在那里咱们能够处理的要求, 但咱们想要的。咱们将向咱们的 基于当前 api 服务器发出请求 (因此若是在一段时间内没有运行, 启动可能会很慢)。

咱们将创建咱们将请求的 url, 由于它表明了咱们将在服务器上请求的时间查询。

我已经在App 组件中定义了方法 getApiUrl() , 所以, 让咱们在中填充该函数。

慢性 api 服务器接受几个变量, 咱们将在表单中进行自定义。它将采起的时区与一个慢性的消息。咱们将简单地开始, 并问慢性库的 pst 时区和当前时间 (now):

class App extends React.Component {
  constructor(props) {
    super(props);
    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() 函数接受一些能够帮助咱们自定义请求的参数。最基本的fetch() 请求只须要一个 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组件已经为咱们处理了这个过程, 因此咱们只须要实现咱们的表单功能。

当一个状态在窗体组件上发生变化时, 它将调用一个称为onFormChange的属性。经过在App 组件中定义此方法, 咱们能够访问该表单的最新版本。

事实上, 咱们将只调用setState() 来跟踪表单容许用户操做的选项:

class App extends React.Component {

// ...
  handleChange(newState) {
    this.setState(newState);
  }

// ...
}

最后, 当用户提交表单时 (按下按钮 或者 按 回车 键在输入字段中单击), 咱们将但愿对时间提出另外一个请求。这意味着咱们能够定义咱们的handleFormSubmit 的属性, 只是调用 fetchCurrentTime()方法:

class App extends React.Component {

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

// ...
}

尝试运行演示和传递不一样的慢速选择。真的颇有趣

在任何状况下, 今天咱们作了至关多的工做, 获取远程数据到咱们的应用程序。然而, 在这一点上, 咱们只有一页的单页应用程序。若是咱们想在咱们的应用程序中显示不一样的页面呢?明天, 咱们将开始在咱们的应用程序中添加多个页面, 以便咱们能够查看不一样的视图。

相关文章
相关标签/搜索