React 快速上手 - 09 数据请求 fetch

目录

React 快速上手 - 09 数据请求 fetch

本文重点在 fetch 基础使用、配置、实战,如果你很熟练了,可以直接 pass

目标

  • 掌握 fetch 使用

    • 基础使用
    • 详细配置
    • 同步请求
    • 跨平台 cross-fetch

环境

  • react 16.3.2
  • fetch 内置
  • cross-fetch 2.2.0

1 fetch 基础使用

1.1 数据结构

我在 easy-mock 上准备了模拟数据

https://www.easy-mock.com/moc...

[
  {
    "id": "610000200102261253","name": "薛洋"
  },{
    "id": "350000199603020600","name": "许磊"
  },{
    "id": "310000198105081812","name": "崔娟"
  },{
    "id": "820000197101010860","name": "石霞"
  }
]

一个列表,两个字段 id name

1.2 读取

fetch(
    'https://www.easy-mock.com/mock/59801fd8a1d30433d84f198c/example/user/all'
  )
    .then(res => res.json())
    .then(data => {
      console.log(data)
      this.setState({users: data})
    })
    .catch(e => console.log('错误:',e))

fetch 是浏览器内置对象,所以我们不用安装包,直接使用

  • 使用流程

    • fetch ...
    • then => res.json()
    • then => data
注意需要执行一次 res.json() 方法才能获取数据

1.3 打印

我们获取数据后,设置 state ,然后正常数据 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.easy-mock.com/mock/59801fd8a1d30433d84f198c/example/user/all'
    )
      .then(res => res.json())
      .then(data => {
        console.log(data)
        this.setState({users: data})
      })
      .catch(e => console.log('错误:',e))
  }

  render() {
    return (
      <div>
        <input type="button" value="点击 http-get 方式获取数据" onClickCapture={this.handleClick} />
        <ul>
          {this.state.users &&
            this.state.users.map((item,index) => (
              <li key={index.toString()}>{item.name}</li>
            ))}
        </ul>
      </div>
    )
  }
}

打印

  • codepen

https://codepen.io/ducafecat/...

2 fetch 配置

我们来好好的看下这个 fetch() 全局方法


我举两个自定义例子,大家体会下

2.1 form 提交

2.1.1 定义 Headers 请求头协议说明

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')
  • 因为是表单,所以设置 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
}
  • method 指定 POST 方式
  • credentials: 'include' 表示每次都带上 cookies
  • headers 请求头协议说明
  • body 数据,格式 key=val&key=val&key=val

2.1.3 请求提交

fetch(
  'https://www.easy-mock.com/mock/59801fd8a1d30433d84f198c/example/user/login',init
)
  .then(res => res.json())
  .then(data => {
    this.setState({user: data})
  })
  .catch(e => console.log('错误:',e))

这里就类似我们第一个基础例子了

  • codepen

https://codepen.io/ducafecat/...

2.2 raw 提交

2.2.1 定义 Headers

let initHeaders = new Headers()
initHeaders.append('Accept','application/json;charset=UTF-8')
  • 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',body
}
  • json 数据需要格式化 JSON.stringify(data,2)

2.2.3 请求提交

fetch(
  'https://www.easy-mock.com/mock/59801fd8a1d30433d84f198c/example/user/login',e))
  • codepen

https://codepen.io/ducafecat/...

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',*/*')
    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',// cookies
      cache: 'no-cache ',// cookies
      headers: initHeaders,body
    }
    fetch(
      'https://www.easy-mock.com/mock/59801fd8a1d30433d84f198c/example/user/login',init
    )
      .then(res => res.json())
      .then(data => {
        this.setState({user: data})
      })
      .catch(e => console.log('错误:',e))
  }
  handlePostJSON() {
    let initHeaders = new Headers()
    initHeaders.append('Accept','application/json;charset=UTF-8')

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

    const init = {
      method: 'POST',e))
  }

  render() {
    return (
      <div>
        <input
          type="button"
          value="点击 http-post form 表单"
          onClickCapture={this.handlePostForm}
        />
        <br />
        <input
          type="button"
          value="点击 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

动图效果

3 fetch 同步 async / wait

3.1 同步写法

async handleClick() {
  try {
    const res = await fetch(
      'https://www.easy-mock.com/mock/59801fd8a1d30433d84f198c/example/user/all'
    )
    const users = await res.json()
    this.setState({users})
  } catch (error) {
    console.log('错误',error)
  }
}
  • 函数本身要定义成 async
  • res.json() 这个方法不要忘记调用
  • 异常处理要用 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.easy-mock.com/mock/59801fd8a1d30433d84f198c/example/user/all'
      )
      const users = await res.json()
      this.setState({users})
    } catch (error) {
      console.log('错误',error)
    }
  }

  render() {
    return (
      <div>
        <input
          type="button"
          value="点击 async / await 方式获取数据"
          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

打印

4 fetch 兼容性

好像 fetch 很强啊,不用安装包,全局方法直接用,但是有一个小问题,对浏览器的依赖,先看下 caniuse 平台的报告:

IE 全阵亡,低版本 Safari 兼容问题,Firefox Chrome Opera 如果特性不开的话也会出问题,懂的同学说可以浏览器配置和打 polyfill 补丁,但是这样需要自己做很多工作,如果你的代码需要跑到 node 端呢(因为API 业务层很有可能复用性很高)。

如果考虑兼容性,所以我们还是用第三方组件

5 cross-fetch 组件

5.1 介绍

cross-fetch

感觉 Star 不是很多么。。。

接着往下看

5.2 多平台支持

README 里说了各种平台支持、知名项目也在用

是真的么。。。

接着往下看

5.3 包研究

打开文件 package.json

来看下这两个包

  • node-fetch

https://github.com/bitinn/nod...

  • whatwg-fetch

指向了 github/fetch

  • github/fetch

https://github.com/github/fetch

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

5.4 例子

  • 安装
yarn add cross-fetch
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.easy-mock.com/mock/59801fd8a1d30433d84f198c/example/user/all'
      )
      const users = await res.json()
      this.setState({users})
    } catch (error) {
      console.log('错误',error)
    }
  }

  render() {
    return (
      <div>
        <input
          type="button"
          value="点击 cross-fetch 组件方式 获取数据"
          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
  • 打印

代码

参考

© 会煮咖啡的猫咪

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom