iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 21
0
Modern Web

為期 30 天的 react 大冒險系列 第 21

react 大冒險-fetch data from API-day 18

  • 分享至 

  • xImage
  •  

react 如同一般 js,可以對 api 發出請求並取回值

send request 的幾種方法

js 是 synchronous 特性的語言,在同時間下,一次只能執行一件事
js 對外部 api 發出請求並將值取回來有幾種方法:
最古老的 XMLHttpRequest / jQuery.ajax / promise / axios (第三方 library)
XMLHttpRequest 不太符合現在的使用,promise 是為了處理 js中異步(async) 的執行所產生的方法
這裡從 promise 開始解說

什麼是 Promise

Promise 物件是即將完成或是即將失敗的非同步操作及其 return 的值
(A promise is an object that may produce a single value some time in the future.)

new Promise( function ( resolve , reject ){...})

如果成功: 執行 resolve,完成 Promise(狀態從 pending => fulfill)
如果錯誤 執行 reject(狀態從 pending => reject)

Promise 的過程

promise 有三種不同的階段

  • pending: 初始時等待的狀態
  • rejected: 請求失敗(error)時的狀態
  • resolved: 請求完成(fulfill)時的狀態

    因為 promise 回傳的物件仍是 promise
    所以可以將 promise 鏈在一起寫(chaining)

實作對外部 api 發出請求的 component

實作一個隨機取得 權力遊戲劇集中名言的 component,把講該句名言的角色 跟 該句名言顯示畫面上
使用者可以對欄位填入想要取的名言數量,如果不填入 預設取的數量為 10

import React from 'react';

export default class GetData extends React.Component {
    constructor(props) {
        super(props);
        this.getData = this.getData.bind(this);
        this.updateData = this.updateData.bind(this);
        this.state = {
            getNum: 10,
            data: [],
            isLoaded: false,
        }

    }
    updateData(e) {
        this.setState({ getNum: e.target.value })
    }
    getData() {
        const quoteNum = this.state.getNum;
        const apiUrl = `https://game-of-thrones-quotes.herokuapp.com/v1/random/${quoteNum}`;
        // console.log(apiUrl);
        if (quoteNum) {
            fetch(apiUrl)
                .then(res => res.json())
                .then(
                    (res) => {
                        this.setState({
                            data: res,
                            isLoaded: true
                        });
                    },
                    // handle error
                    (error) => {
                        this.setState({
                            isLoaded: true,
                            error
                        });
                    }
                )
        } else {
            return '';
        }
    }
    render() {
        const { getNum, data } = this.state;
        return (
            <>
                <input type="number" value={getNum} onChange={this.updateData} />
                <button onClick={this.getData}>fetch quotes</button>
                {data.map((eachData) => <div>
                    <h2>{eachData.character.name}</h2>
                    <p>{eachData.sentence}</p>
                </div>)}
            </>
        )
    }
}

這時候按下 fetch quotes 按鈕,便會顯示出得到的隨機名言

但如果希望頁面載入後就取得 data 的話,則要使用 react 中內建的 lifecycle method


上一篇
react 大冒險-unidirectional flow 單向資料流-day 17-2
下一篇
react 大冒險-Lifecycle method-day 19
系列文
為期 30 天的 react 大冒險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言