日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

React 快速上手 - 09 數(shù)據(jù)請求 fetch

 huowufenghuang 2019-01-28

React 快速上手 - 09 數(shù)據(jù)請求 fetch

本文重點(diǎn)在 fetch 基礎(chǔ)使用、配置、實(shí)戰(zhàn),如果你很熟練了,可以直接 pass

目標(biāo)

  • 掌握 fetch 使用
    • 基礎(chǔ)使用
    • 詳細(xì)配置
    • 同步請求
    • 跨平臺(tái) cross-fetch

環(huán)境

  • react 16.3.2
  • fetch 內(nèi)置
  • cross-fetch 2.2.0

1 fetch 基礎(chǔ)使用

1.1 數(shù)據(jù)結(jié)構(gòu)

我在 easy-mock 上準(zhǔn)備了模擬數(shù)據(jù)

www./mock/59801f…

[
  {
    "id": "610000200102261253",
    "name": "薛洋"
  },
  {
    "id": "350000199603020600",
    "name": "許磊"
  },
  {
    "id": "310000198105081812",
    "name": "崔娟"
  },
  {
    "id": "820000197101010860",
    "name": "石霞"
  }
]
復(fù)制代碼

一個(gè)列表,兩個(gè)字段 id name

1.2 讀取

  fetch(
    ''https://www./mock/59801fd8a1d30433d84f198c/example/user/all''
  )
    .then(res => res.json())
    .then(data => {
      console.log(data)
      this.setState({users: data})
    })
    .catch(e => console.log(''錯(cuò)誤:'', e))
復(fù)制代碼

fetch 是瀏覽器內(nèi)置對象,所以我們不用安裝包,直接使用

  • 使用流程
    • fetch ...
    • then => res.json()
    • then => data

注意需要執(zhí)行一次 res.json() 方法才能獲取數(shù)據(jù)

1.3 打印

我們獲取數(shù)據(jù)后,設(shè)置 state ,然后正常數(shù)據(jù) render 就行,完整代碼

import React, {Component} from ''react''

class RequestView extends Component {
  constructor(props) {
    super(props)
    this.state = {users: []}
    this.handleClick = this.handleClick.bind(this)
  }
  handleClick() {
    fetch(
      ''https://www./mock/59801fd8a1d30433d84f198c/example/user/all''
    )
      .then(res => res.json())
      .then(data => {
        console.log(data)
        this.setState({users: data})
      })
      .catch(e => console.log(''錯(cuò)誤:'', e))
  }

  render() {
    return (
      <div>
        <input type="button" value="點(diǎn)擊 http-get 方式獲取數(shù)據(jù)" onClickCapture={this.handleClick} />
        <ul>
          {this.state.users &&
            this.state.users.map((item, index) => (
              <li key={index.toString()}>{item.name}</li>
            ))}
        </ul>
      </div>
    )
  }
}
復(fù)制代碼

打印

fetch

  • codepen

codepen.io/ducafecat/p…

2 fetch 配置

我們來好好的看下這個(gè) fetch() 全局方法

fetch-init-1
fetch-init-2

我舉兩個(gè)自定義例子,大家體會(huì)下

2.1 form 提交

2.1.1 定義 Headers 請求頭協(xié)議說明

let initHeaders = new Headers()
initHeaders.append(''Accept'', ''application/json, text/plain, */*'')
initHeaders.append(''Cache-Control'', ''no-cache'')
initHeaders.append(''Content-Type'', ''application/x-www-form-urlencoded'')
復(fù)制代碼
  • 因?yàn)槭潜韱危栽O(shè)置 application/x-www-form-urlencoded

2.1.2 定義 init 配置

let data = {uid: 1011}
let body = `uid=${data.uid}`

const init = {
  method: ''POST'',
  credentials: ''include'', // cookies
  cache: ''no-cache '', // cookies
  headers: initHeaders,
  body
}
復(fù)制代碼
  • method 指定 POST 方式
  • credentials: ''include'' 表示每次都帶上 cookies
  • headers 請求頭協(xié)議說明
  • body 數(shù)據(jù),格式 key=val&key=val&key=val

2.1.3 請求提交

fetch(
  ''https://www./mock/59801fd8a1d30433d84f198c/example/user/login'',
  init
)
  .then(res => res.json())
  .then(data => {
    this.setState({user: data})
  })
  .catch(e => console.log(''錯(cuò)誤:'', e))
復(fù)制代碼

這里就類似我們第一個(gè)基礎(chǔ)例子了

  • codepen

codepen.io/ducafecat/p…

2.2 raw 提交

2.2.1 定義 Headers

let initHeaders = new Headers()
initHeaders.append(''Accept'', ''application/json, text/plain, */*'')
initHeaders.append(''Cache-Control'', ''no-cache'')
initHeaders.append(''Content-Type'', ''application/json;charset=UTF-8'')
復(fù)制代碼
  • Content-Type 類型需要定義成 application/json;charset=UTF-8

2.2.2 定義 init

let data = {uid: 1011}
let body = JSON.stringify(data, null, 2)

const init = {
  method: ''POST'',
  credentials: ''include'', // cookies
  cache: ''no-cache '', // cookies
  headers: initHeaders,
  body
}
復(fù)制代碼
  • json 數(shù)據(jù)需要格式化 JSON.stringify(data, null, 2)

2.2.3 請求提交

fetch(
  ''https://www./mock/59801fd8a1d30433d84f198c/example/user/login'',
  init
)
  .then(res => res.json())
  .then(data => {
    this.setState({user: data})
  })
  .catch(e => console.log(''錯(cuò)誤:'', e))
復(fù)制代碼
  • codepen

codepen.io/ducafecat/p…

2.3 完整例子

代碼

import React, {Component} from ''react''

class RequestView extends Component {
  constructor(props) {
    super(props)
    this.state = {user: null}
    this.handlePostForm = this.handlePostForm.bind(this)
    this.handlePostJSON = this.handlePostJSON.bind(this)
  }
  handlePostForm() {
    let initHeaders = new Headers()
    initHeaders.append(''Accept'', ''application/json, text/plain, */*'')
    initHeaders.append(''Cache-Control'', ''no-cache'')
    initHeaders.append(''Content-Type'', ''application/x-www-form-urlencoded'')

    let data = {uid: 1011}
    let body = `uid=${data.uid}`

    const init = {
      method: ''POST'',
      credentials: ''include'', // cookies
      cache: ''no-cache '', // cookies
      headers: initHeaders,
      body
    }
    fetch(
      ''https://www./mock/59801fd8a1d30433d84f198c/example/user/login'',
      init
    )
      .then(res => res.json())
      .then(data => {
        this.setState({user: data})
      })
      .catch(e => console.log(''錯(cuò)誤:'', e))
  }
  handlePostJSON() {
    let initHeaders = new Headers()
    initHeaders.append(''Accept'', ''application/json, text/plain, */*'')
    initHeaders.append(''Cache-Control'', ''no-cache'')
    initHeaders.append(''Content-Type'', ''application/json;charset=UTF-8'')

    let data = {uid: 1011}
    let body = JSON.stringify(data, null, 2)

    const init = {
      method: ''POST'',
      credentials: ''include'', // cookies
      cache: ''no-cache '', // cookies
      headers: initHeaders,
      body
    }
    fetch(
      ''https://www./mock/59801fd8a1d30433d84f198c/example/user/login'',
      init
    )
      .then(res => res.json())
      .then(data => {
        this.setState({user: data})
      })
      .catch(e => console.log(''錯(cuò)誤:'', e))
  }

  render() {
    return (
      <div>
        <input
          type="button"
          value="點(diǎn)擊 http-post form 表單"
          onClickCapture={this.handlePostForm}
        />
        <br />
        <input
          type="button"
          value="點(diǎn)擊 http-post json raw 格式"
          onClickCapture={this.handlePostJSON}
        />
        {this.state.user && (
          <ul>
            <li>ID: {this.state.user.id}</li>
            <li>Name: {this.state.user.name}</li>
          </ul>
        )}
      </div>
    )
  }
}

export default RequestView

復(fù)制代碼

動(dòng)圖效果

fetch-form-raw

3 fetch 同步 async / wait

3.1 同步寫法

async handleClick() {
  try {
    const res = await fetch(
      ''https://www./mock/59801fd8a1d30433d84f198c/example/user/all''
    )
    const users = await res.json()
    this.setState({users})
  } catch (error) {
    console.log(''錯(cuò)誤'', error)
  }
}
復(fù)制代碼
  • 函數(shù)本身要定義成 async
  • res.json() 這個(gè)方法不要忘記調(diào)用
  • 異常處理要用 try ... catch ...

3.2 完成例子

代碼

import React, {Component} from ''react''

class RequestView extends Component {
  constructor(props) {
    super(props)
    this.state = {users: []}
    this.handleClick = this.handleClick.bind(this)
  }
  async handleClick() {
    try {
      const res = await fetch(
        ''https://www./mock/59801fd8a1d30433d84f198c/example/user/all''
      )
      const users = await res.json()
      this.setState({users})
    } catch (error) {
      console.log(''錯(cuò)誤'', error)
    }
  }

  render() {
    return (
      <div>
        <input
          type="button"
          value="點(diǎn)擊 async / await 方式獲取數(shù)據(jù)"
          onClickCapture={this.handleClick}
        />
        <ul>
          {this.state.users &&
            this.state.users.map((item, index) => (
              <li key={index.toString()}>{item.name}</li>
            ))}
        </ul>
      </div>
    )
  }
}

export default RequestView

復(fù)制代碼

打印

fetch-await

4 fetch 兼容性

好像 fetch 很強(qiáng)啊,不用安裝包,全局方法直接用,但是有一個(gè)小問題,對瀏覽器的依賴,先看下 caniuse 平臺(tái)的報(bào)告:

caniuse-fetch

IE 全陣亡,低版本 Safari 兼容問題,Firefox Chrome Opera 如果特性不開的話也會(huì)出問題,懂的同學(xué)說可以瀏覽器配置和打 polyfill 補(bǔ)丁,但是這樣需要自己做很多工作,如果你的代碼需要跑到 node 端呢(因?yàn)?code>API 業(yè)務(wù)層很有可能復(fù)用性很高)。

如果考慮兼容性,所以我們還是用第三方組件

5 cross-fetch 組件

5.1 介紹

cross-fetch

cross-fetch

感覺 Star 不是很多么。。。

接著往下看

5.2 多平臺(tái)支持

README 里說了各種平臺(tái)支持、知名項(xiàng)目也在用

是真的么。。。

接著往下看

Supported environments

5.3 包研究

打開文件 package.json

dependencies

來看下這兩個(gè)包

  • node-fetch

github.com/bitinn/node…

node-fetch

  • whatwg-fetch

ducafecat_2018-05-27-16-08-31

指向了 github/fetch

  • github/fetch

github.com/github/fetc…

github-fetch

好多 Star 看著就放心,大家用吧

5.4 例子

  • 安裝
yarn add cross-fetch
復(fù)制代碼
  • 代碼
import React, {Component} from ''react''
import fetch from ''cross-fetch''

class RequestView extends Component {
  constructor(props) {
    super(props)
    this.state = {users: []}
    this.handleClick = this.handleClick.bind(this)
  }
  async handleClick() {
    try {
      const res = await fetch(
        ''https://www./mock/59801fd8a1d30433d84f198c/example/user/all''
      )
      const users = await res.json()
      this.setState({users})
    } catch (error) {
      console.log(''錯(cuò)誤'', error)
    }
  }

  render() {
    return (
      <div>
        <input
          type="button"
          value="點(diǎn)擊 cross-fetch 組件方式 獲取數(shù)據(jù)"
          onClickCapture={this.handleClick}
        />
        <ul>
          {this.state.users &&
            this.state.users.map((item, index) => (
              <li key={index.toString()}>{item.name}</li>
            ))}
        </ul>
      </div>
    )
  }
}

export default RequestView
復(fù)制代碼
  • 打印

Cross-Fetch

代碼

參考


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多