第 4 章 React ajax

4.1 理解

4.1.1 前置说明

  1. React 本身只关注于界面, 并不包含发送 ajax 请求的代码

  2. 前端应用需要通过 ajax 请求与后台进行交互(json 数据)

  3. react 应用中需要集成第三方 ajax 库(或自己封装)

4.1.2 常用的 ajax 请求库

  1. jQuery: 比较重, 如果需要另外引入不建议使用

  2. axios: 轻量级, 建议使用

    1. 封装 XmlHttpRequest 对象的 ajax

    2. promise 风格

    3. 可以用在浏览器端和 node 服务器端

4.2. axios

4.2.1. 文档

https://github.com/axios/axios

4.3 React配置代理

4.3.1 方法一

在package.json中追加如下配置

"proxy":"http://localhost:5000"

说明:

  1. 优点:配置简单,前端请求资源时可以不加任何前缀。

  2. 缺点:不能配置多个代理。

  3. 工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)

4.3.2 方法二

  1. 第一步:创建代理配置文件
在src下创建配置文件:src/setupProxy.js
  1. 编写setupProxy.js配置具体代理规则:
const {createProxyMiddleware} = require('http-proxy-middleware')
   
module.exports = function(app) {
  app.use(
    createProxyMiddleware('/api1', {  //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000)
      target: 'http://localhost:5000', //配置转发目标地址(能返回数据的服务器地址)
      changeOrigin: true, //控制服务器接收到的请求头中host字段的值
      /*
        changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
        changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
        changeOrigin默认值为false,但我们一般将changeOrigin值设为true
      */
      pathRewrite: {'^/api1': ''} //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
    }),
    createProxyMiddleware('/api2', { 
      target: 'http://localhost:5001',
      changeOrigin: true,
      pathRewrite: {'^/api2': ''}
    })
  )
}

说明:

  1. 优点:可以配置多个代理,可以灵活的控制请求是否走代理。

  2. 缺点:配置繁琐,前端请求资源时必须加前缀。

4.3.3 代码

代码:

getMsg = () => {
  // axios.get('http://localhost:5000/students').then(res=>{console.log(res.data)},err=>{console.log(err.message)})
  axios({
    method: 'get',
    url: '/api1/students'
  }).then(
    (res) => { console.log(res.data) },
    (err) => { console.log(err.message) }
  )
}
getCarMsg = ()=>{
  axios({
    url:'/api2/cars',
    method:'get'
  }).then(
    (res)=>{console.log(res.data)},
    (err)=>{console.log(err.message)}
  )
}

效果:

![image.png](https://img-blog.csdnimg.cn/img_convert/8968288c2bf3e81c131897a0f75e393c.png#clientId=u6898f75a-994e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=431&id=u9a7a5548&margin=[object Object]&name=image.png&originHeight=861&originWidth=1621&originalType=binary&ratio=1&rotation=0&showTitle=false&size=129626&status=done&style=none&taskId=uba5dfba7-ab90-4d98-88db-37496ccd090&title=&width=810.5)

4.4 案例—github 用户搜索

请求地址: https://api.github.com/search/users?q=xxxxxx

4.5 消息订阅-发布机制

  1. 工具库: PubSubJS

  2. 下载: npm install pubsub-js --save

  3. 使用:

    1. import PubSub from ‘pubsub-js’ //引入
import PubSub from 'pubsub-js'
  1. PubSub.subscribe(‘delete’, function(data){ }); //订阅
componentDidMount =()=>{
  this.token = PubSub.subscribe('updateState',(_,stateObj)=>{
    console.log('list订阅的消息更新了',stateObj)
    this.setState(stateObj)
  })
}
componentWillUnmount = ()=>{
  PubSub.unsubscribe(this.token)
}
  1. PubSub.publish(‘delete’, data) //发布消息
PubSub.publish('updateState', { isFirst: false, isLoading: true })

代码:

List代码:

import React, { Component } from 'react'
import './index.css'
import PubSub from 'pubsub-js'

export default class List extends Component {
  state={
    users:[],
    isFirst:true,
    isLoading:false,
    err:''
  }
  componentDidMount =()=>{
    this.token = PubSub.subscribe('updateState',(_,stateObj)=>{
      console.log('list订阅的消息更新了',stateObj)
      this.setState(stateObj)
    })
  }
  componentWillUnmount = ()=>{
    PubSub.unsubscribe(this.token)
  }
  render() {
    const { users ,isFirst,isLoading,err} = this.state//html_url,avatar_url,login
    
    return (
      <div  className="row">
        {
          isFirst?<h2>输入关键词,点击搜索</h2>:
          isLoading?<h2>Loading</h2>:
          err?<h2>{err}</h2>:
          users.map((user) => {
            return (<div key={user.id} className="card">
              <a href={user.html_url} target="_blank" rel="noreferrer">
                <img alt='avatar' src={user.avatar_url} style={{ width: '100px' }} />
              </a>
              <p className="card-text">{user.login}</p>
            </div>)
          })
        }
      </div>
    )
  }
}

Search代码:

import axios from 'axios'
import React, { Component } from 'react'
import PubSub from 'pubsub-js'

export default class Search extends Component {
  render() {
    return (
      <section className="jumbotron">
        <h3 className="jumbotron-heading">搜索github用户</h3>
        <div>
          <input ref={c => { this.input = c }} type="text" placeholder="输入关键词搜索" />&nbsp;
          <button onClick={this.search}>搜索</button>
        </div>
      </section>
    )

  }
  search = () => {
    const { input } = this
    console.log(input.value)
    // this.props.updateAppState({isFirst:false,isLoading:true})
    PubSub.publish('updateState', { isFirst: false, isLoading: true })
    axios({
      method: 'get',
      url: `https://api.github.com/search/users?q=${input.value}`
    }).then(
      (res) => {
        console.log(res.data)
        // this.props.updateAppState({users:res.data.items,isLoading:false,err:""})
        PubSub.publish('updateState', { users: res.data.items, isLoading: false, err: "" })
      },
      (err) => {
        console.log(err.message)
        // this.props.updateAppState({err:err.message,isLoading:false})
        PubSub.publish('updateState', { err: err.message, isLoading: false })
      }
    )
    input.value = ''
  }
}

4.6 扩展:Fetch

4.6.1. 文档

  1. https://github.github.io/fetch/

  2. https://segmentfault.com/a/1190000003810652

4.6.2. 特点

  1. fetch: 原生函数,不再使用 XmlHttpRequest 对象提交 ajax 请求
  2. 老版本浏览器可能不支持

4.6.3 代码

简单写法:

//fetch的简单写法
try{
  const res = await fetch(`https://api.github.com/search/users?q=${input.value}`)
  let data = await res.json()
  PubSub.publish('updateState', { users: data.items, isLoading: false, err: "" })
  //console.log('easyeasyeasy',data.items)
}
catch(e){
  PubSub.publish('updateState', { err: e.message, isLoading: false })
  //console.log('wwwwwwwwwwwwwwwwwwwww',e)
}

复杂写法:

        //fetch的复杂写法
fetch('https://api.github.com/search/users?q=nino')
  .then(
  	(res) => { console.log('success') ;return res.json()},
  	(err) => { console.log('error',err);return err }
  )
  .then(
  	(res) => { console.log(res.items) },
  	(err) => { console.log(err.message) }
	) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呐呐呐呐。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值