【全棧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();
  }

// ...
}

嘗試運行演示和傳遞不一樣的慢速選擇。真的頗有趣

在任何狀況下, 今天咱們作了至關多的工做, 獲取遠程數據到咱們的應用程序。然而, 在這一點上, 咱們只有一頁的單頁應用程序。若是咱們想在咱們的應用程序中顯示不一樣的頁面呢?明天, 咱們將開始在咱們的應用程序中添加多個頁面, 以便咱們能夠查看不一樣的視圖。

相關文章
相關標籤/搜索