zl程序教程

您现在的位置是:首页 >  前端

当前栏目

03-React网络通信(Axios, PubSubJs, Fetch)

React 03 Axios fetch 网络通信
2023-06-13 09:11:25 时间

创建项目

create-react-app react_axios

添加axios依赖

yarn add axios

配置代理

在package.json中配置

"proxy": "http://localhost:8080"

使用时需要将访问端口改为自身端口

import React, {Component} from 'react';
import axios from "axios";

class App extends Component {
    queryData = () => {
        # 访问3000端口, 然后通过代理,访问8080
        axios.get("http://localhost:3000/students").then(
            response=> {
                console.log(response)
            },
            error => {
                console.log(error)
            }
        )
    }
    render() {
        return (
            <div>
                <button onClick={this.queryData}>获取数据</button>
            </div>
        );
    }
}

export default App;

但是这样会存在一个问题, 那就是访问自身3000存在的资源就不会转发给8080

修改为

其实就是public/index.html

多代理配置

在src下新建setupProxy.js, 记得删除package.json中的proxy

// 需要写 CJS语法

// 导入代理中间件
const {createProxyMiddleware} = require('http-proxy-middleware')

module.exports = function (app) {
    app.use(
        createProxyMiddleware('/test', {
            target: 'http://localhost:8080',
            changeOrigin: true,
            pathRewrite:{
                '^/test':''
            }
        }),
        createProxyMiddleware('/dev', {
            target: 'http://localhost:8081',
            changeOrigin: true,
            pathRewrite:{
                '^/dev':''
            }
        })
    )
}

使用时添加前缀

这样就可以转发多个网络请求了, 通过前缀区分,要代理到哪里

连续解构赋值

const key = {
  value:{
    title:'123'
  }
}
# 连续解构赋值
const {value:{title}} = key
# 只能使用title, 而不能使用value

解构赋值后重命名

const key = {
  value:{
    title:'123'
  }
}
# 连续解构赋值 将title重命名为标题
const {value:{title:bt}} = key

消息订阅与发布(PubSubJs)

添加依赖

yarn add pubsub-js

使用

App.js

import React, {Component} from 'react';
import axios from "axios";
import Pub from "./components/pub/pub";
import Sub from "./components/sub/sub";

class App extends Component {

    render() {
        return (
            <div>
                <Pub/>
                <Sub/>
            </div>
        );
    }
}

export default App;

Pub.js

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

class Pub extends Component {
    render() {
        return (
            <div>
                <button onClick={this.send}>发送消息</button>
            </div>
        );
    }
    send = () => {
        const items = ['a','b','c']
        PubSub.publish('pub',items)
        console.log("发送数据")
    }
}

export default Pub;

Sub.js

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

class Sub extends Component {
    state = {
        items: ['html', 'js', 'css']
    }
    componentDidMount = () => {
        // 订阅消息
        console.log("订阅消息")
        this.token = PubSub.subscribe('pub', (_, items) => {
            console.log("sub接收到数据", items);
            this.setState({items})
        })
    }

    componentWillUnmount() {
        // 在组件卸载时取消订阅
        PubSub.unsubscribe(this.token)
    }

    render() {
        const {items} = this.state
        return (
            <div>
                <ul>
                    {
                        items.map(item => {
                            return <li key={item}>{item}</li>
                        })
                    }
                </ul>
            </div>
        );
    }
}

export default Sub;

执行结果

效果没有问题, 但是消息被订阅了两次

componentDidMount函数被连续执行两次的问题

因为我在订阅之后发现这个生命周期被连续执行两次,导致一下订阅了两次,出现问题

解决办法

把index.js中的React.StrictMode删除即可

删除后发现剩余此一次一次了

扩展知识: Fetch

文档

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

特点

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

Get请求

fetch('http://localhost:3000/test/students').then(
  response => {
    console.log("联系服务器成功",response)
    return response.json()
  }
).then(
  response => {
    console.log("获取数据成功",response)
  }
).catch(
  error => {
    console.log("失败",error)
  }
)

Post请求

const items = ['a','b','c']
fetch('http://localhost:3000/test/students',{
  method:'POST',
  body:JSON.stringify(items)
}).then(
  response => {
    console.log("联系服务器成功",response)
    return response.json()
  }
).then(
  response => {
    console.log("获取数据成功",response)
  }
).catch(
  error => {
    console.log("失败",error)
  }
)

优化写法

try {
  const response = await fetch('http://localhost:3000/test/students', {
    method: 'POST',
    body: JSON.stringify(items)
  })
  const data = await response.json()
  console.log(data)
} catch (e) {
  console.log("失败了",e)
}

记得在外部函数写async