1、前言

        因为最近在进行老系统用新框架改造,正好用到了react,就顺便整理了一下react中对axios进行封装的相关知识点和步骤。

2、如何封装

        可以参考一下chat gpt给出的回答。

        

 

         我大概总结一下,其实就是使用axios.create创建一个axios的实例,然后我们每次发get/post请求,都直接调用这个创建好的axios实例就行了。

3、相关代码

相关代码gitee地址:https://gitee.com/wulinchun/my-react-ts.git

Step1、创建一个typescript的react工程项目 。

npx create-react-app my-react-ts --template typescript

        如果不加 --template typescript,react默认建的是javascript工程。我之前去网上学习react的时候,许多教程都是基于js,jsx创建的react工程,但我在公司开发的react项目都是typescript的。typescript是javascript的增强版,我之前一直都是写javascript、jquery这套的,typescript之前没接触过。我没怎么系统学习过typescript语言,就我在实际工作开发而言。typescript增加了一些结构类型的定义。比如我在.ts里面可以定义一个interface结构用于接收后端的数据,interface结构中我可以详细的定义每一个变量的类型:string,number,boolean等等。不确定的类型则用any。相比较而言javascript就没这么强大。typescript的编译比javascript严格。javascript是弱类型的,只要不是什么涉及到计算的,你把一个字符串型的数值赋值给一个数值类型的变量也没啥问题。你直接用var定义就行了。但typescript就不可以了。

        不过从编译效率上来说的话,因为node.js不能直接执行.ts文件,因此编译的时候会多一步把typescript转为javascript,因此typescript要比javascript慢一点。 

关于typescript更多的了解可参考:

​​​​​​TypeScript 与 JavaScript:你应该知道的区别 - 掘金 (juejin.cn)

文档简介 · TypeScript中文网 · TypeScript——JavaScript的超集 (tslang.cn)

Step2、react前端代码

        这是我的工程目录结构

request.ts(用于封装axios实例)

import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import axios from 'axios'
interface AxiosTokenInstance extends AxiosInstance {
   
}
// 创建一个axios实例
const instance: AxiosTokenInstance = axios.create({
    baseURL: '/',
    timeout: 5000,
    responseType: 'json',
    headers: {
      'Content-Type': 'application/json',
    },
  })

const {request,get,post} = instance;
//暴露axios实例
export {request,get,post,instance};

returnType.ts(接口返回值数据结构)

export interface ResType<R>{
    code:number;
    message:string;
    data:R;
}

setupProxy.js(配置代理,注意必须是.js代理文件,不能用setupProxy.ts,因为npm start启动的时候无法加载.ts的配置文件)

const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
    app.use(
        '/api',
        createProxyMiddleware({
            target: 'http://127.0.0.1:80',
            changeOrigin: true,
            pathRewrite: {
                '^/api': '',
            }
        })
    );
    app.use(
        '/api1',
        createProxyMiddleware({
            target: 'http://localhost:8082',
            changeOrigin: true,
            pathRewrite: {
                '^/api1': '',
            }
        })
    );
};

src\pages\Home\index.tsx(页面组件)

import React,{useState} from "react";
import {PeopleDTO,listAllPeople,getPeople,getPeople1,PeopleV2DTO} from './service'
import {useRequest} from 'ahooks';

const Home:React.FC=()=>{
    const [peopleDTOList,setpeopleDTOList]=useState<PeopleDTO[]>([]);

    const [age,setAge]=useState('')
    const [peopleId,setPeopleId]=useState('')
    const [peopleName,setPeopleName]=useState('')
    const [position,setPosition]=useState('')
    const [subordinateList,setSubordinateList]=useState<PeopleV2DTO[]>([]);

    const [searchContent, setSearchContent] = useState<string>('');



    const listPeople=()=>{
        //get请求无参数
        listAllPeople().then((response) => {
            const result = response.data;
             console.log(response);
             console.log(result);
             setpeopleDTOList(result.PeopleDTOList);
             console.log(peopleDTOList)
        });
    };

    const getOnePeople=()=>{
        //get请求带参数
        getPeople(searchContent).then((response) => {
            console.log(searchContent)
            const result = response.data;
            console.log(response);
            console.log(result);
            setAge(result.age);
            setPeopleId(result.peopleId);
            setPeopleName(result.peopleName);
            setPosition(result.position);
            setSubordinateList(result.subordinate);
        });
    };

    const getOnePeople1=()=>{
        //post请求带json参数
        getPeople1({PeopleId:searchContent}).then((response) => {
            console.log(searchContent)
            const result = response.data;
            console.log(response);
            console.log(result);
            setAge(result.age);
            setPeopleId(result.peopleId);
            setPeopleName(result.peopleName);
            setPosition(result.position);
            setSubordinateList(result.subordinate);
        });
    };


   
    return(
        <div>
            <h1>首页</h1>
            <button onClick={() => listPeople()}>listAllPeople</button>
            <input
               placeholder="请输入待搜索人员" 
               value={searchContent}
               onChange={(e) => {
                setSearchContent(e.target.value);
              }}
            />
            <button onClick={() => getOnePeople()}>getOnePeople</button>
            <button onClick={() => getOnePeople1()}>getOnePeople1</button>
            <table>
                <tbody>
                    {peopleDTOList.map((items, index)=>(
                        <tr key={index}>
                            <th>ID:</th><td>{items.peopleId}</td>
                            <th>姓名:</th><td>{items.peopleName}</td>
                            <th>年龄:</th><td>{items.age}</td>
                            <th>职位:</th><td>{items.position}</td>
                            <th>下属:</th>
                            <td>
                                {items.subordinate.map((it,idx)=>(
                                    <label key={idx}>{it.name}~{it.age}</label>
                                ))}
                            </td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    )
   
    

};

export default Home;

src\pages\Home\service.ts(定义数据结构以及请求后端接口)

import { get,post } from '../../../src/utils/request';
import {ResType} from '../../../src/utils/returnType'


export interface PeopleDTO {
    peopleId: string;
    peopleName: string;
    age: string;
    position: string;
    subordinate: PeopleV2DTO[];
}

export interface PeopleV2DTO {
    name: string;
    age: string;
}

export interface PeopleDTOList{
    PeopleDTOList: PeopleDTO[];
}

export interface PeopleId{
    PeopleId: string;
}

export const listAllPeople:(
) =>Promise<ResType<PeopleDTOList>>=()=>{
    return get('api/root/listPeople.asp')
}

export const getPeople:(
    params:string,
) =>Promise<ResType<PeopleDTO>>=(params)=>{
    return get(`api/root/getPeople.asp?PeopleId=${params}`,{})
};

export const getPeople1:(
    params:PeopleId,
) =>Promise<ResType<PeopleDTO>>=(params)=>{
    return post('api1/login/getPeople1',params)
};

src\index.tsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import Home  from './pages/Home';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    {/* <App /> */}
    <Home/>
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Step3、后端接口

vbscript接口,部署在http://127.0.0.1:80上

1、/root/listPeople.asp

<%
Response.Charset="utf-8"
Set util=CreateObject("util.WSC")
Set bzExample=CreateObject("bzExample.WSC")

Set oJsonResponse = util.InitAspJson()


ReDim Preserve arrDetail(2,3)
arrDetail(0,0)="李五"
arrDetail(1,0)="20"

arrDetail(0,1)="王五"
arrDetail(1,1)="22"

arrDetail(0,2)="赵六"
arrDetail(1,2)="25"

'Response.Write Ubound(arrDetail,2)&"<br/>"

With oJsonResponse.data
   .Add "PeopleDTOList",oJsonResponse.Collection()
        With .item("PeopleDTOList")
            .Add 0,oJsonResponse.Collection()
            With .item(0)
                .Add "peopleId","zhangsan" 
                .Add "peopleName","张三"
                .Add "age","30"
                .Add "position","Manager" 
                .Add "subordinate",oJsonResponse.Collection()
                With .item("subordinate")
                    indexI = 0
                    for indexI=0 to Ubound(arrDetail,2)-1
                        'Response.Write "indexI="&indexI&"<br/>"
                        .Add indexI,oJsonResponse.Collection()
                        With .item(indexI)
                            .Add "name",arrDetail(0,indexI)
                            .Add "age",arrDetail(1,indexI)  
                        End With

                        'indexI = indexI +1
                    next
                End With
            End With

            .Add 1,oJsonResponse.Collection()
            With .item(1)
                .Add "peopleId","lisi" 
                .Add "peopleName","李四"
                .Add "age","40"
                .Add "position","Manager" 
                .Add "subordinate",oJsonResponse.Collection()
                With .item("subordinate")
                    indexI = 0
                    for indexI=0 to Ubound(arrDetail,2)-1
                        'Response.Write "indexI="&indexI&"<br/>"
                        .Add indexI,oJsonResponse.Collection()
                        With .item(indexI)
                            .Add "name",arrDetail(0,indexI)
                            .Add "age",arrDetail(1,indexI)  
                        End With

                        'indexI = indexI +1
                    next
                End With
            End With
        End With
End With

Response.Write oJsonResponse.JSONoutput()
%>

2、/root/getPeople.asp

<%
Response.Charset="utf-8"
Set util=CreateObject("util.WSC")
Set bzExample=CreateObject("bzExample.WSC")

Set oJsonResponse = util.InitAspJson()

peopleId=request("PeopleId")

ReDim Preserve arrDetail(2,3)
arrDetail(0,0)="李五"
arrDetail(1,0)="20"

arrDetail(0,1)="王五"
arrDetail(1,1)="22"

arrDetail(0,2)="赵六"
arrDetail(1,2)="25"

'Response.Write Ubound(arrDetail,2)&"<br/>"

With oJsonResponse.data
    if peopleId="zhangsan" then
    .Add "peopleId","zhangsan" 
        .Add "peopleName","张三"
        .Add "age","30"
        .Add "position","Manager" 
        .Add "subordinate",oJsonResponse.Collection()
        With .item("subordinate")
            indexI = 0
            for indexI=0 to Ubound(arrDetail,2)-1
                'Response.Write "indexI="&indexI&"<br/>"
                .Add indexI,oJsonResponse.Collection()
                With .item(indexI)
                    .Add "name",arrDetail(0,indexI)
                    .Add "age",arrDetail(1,indexI)  
                End With

                'indexI = indexI +1
            next
        End With
    end if

    if peopleId="lisi" then
    .Add "peopleId","lisi" 
        .Add "peopleName","李四"
        .Add "age","40"
        .Add "position","Manager" 
        .Add "subordinate",oJsonResponse.Collection()
        With .item("subordinate")
            indexI = 0
            for indexI=0 to Ubound(arrDetail,2)-1
                'Response.Write "indexI="&indexI&"<br/>"
                .Add indexI,oJsonResponse.Collection()
                With .item(indexI)
                    .Add "name",arrDetail(0,indexI)
                    .Add "age",arrDetail(1,indexI)  
                End With

                'indexI = indexI +1
            next
        End With
    end if
End With

Response.Write oJsonResponse.JSONoutput()
%>

java接口,部署在http://localhost:8082上

1、/login/getPeople1

@PostMapping("/getPeople1")
    @ResponseBody
    public PeopleDTO getPeople1(@RequestBody Map<String, Object> map) {
        String peopleId = map.get("PeopleId").toString();
        PeopleDTO peopleDTO1 = new PeopleDTO("zhangsan", "张三", "30", "Manager", null);
        PeopleDTO peopleDTO2 = new PeopleDTO("lisi", "李四", "40", "Manager", null);
        PeopleV2DTO peopleV2DTO1 = new PeopleV2DTO("李五", "20");
        PeopleV2DTO peopleV2DTO2 = new PeopleV2DTO("王五", "22");
        PeopleV2DTO peopleV2DTO3 = new PeopleV2DTO("赵六", "25");
        List<PeopleV2DTO> peopleV2DTOList = Arrays.asList(peopleV2DTO1, peopleV2DTO2, peopleV2DTO3);
        peopleDTO1.setSubordinate(peopleV2DTOList);
        peopleDTO2.setSubordinate(peopleV2DTOList);
        if (peopleId.equals("zhangsan")) {
            return peopleDTO1;
        }
        if (peopleId.equals("lisi")) {
            return peopleDTO2;
        }
        return null;
    }

运行效果 

 

4、总结

        前端进行http请求后端接口可以有三个选择:ajax,axios和fetch。ajax普遍用于jquery中的。axios和fetch都是用于vue,react之类的前端主流框架。更推荐使用axios而不是fetch,因为fetch比较老,对浏览器的兼容性不如axios。并且由于fetch是偏向于底层原生的嘛。所以fetch所提供的功能不如axios强大。

axios与fetch比较可以参考一下这篇:Axios or fetch():你更中意哪一个? - 掘金 (juejin.cn)

简单概括一下 axios与fetch的差异:

  • axios对浏览器的兼容性比fetch更广。
  • axios的返回值可以自动转为json格式,但fetch会返回一个包含响应结果的promise,所以fetch需要手动使用json()方法进行一个转换。
  • axios在一些基础配置使用上,比如配置拦截器,配置响应超时时间,同时发起多个响应请求上要比fetch更加快捷方便。

        在实际使用axios过程中,都会倾向于先对axios进行一个封装。统一配置像baseURL、timeout、responseType、headers等等属性,以便于开箱即用。

        

5、参考资料

最新React使用 http-proxy-middleware解决多跨域问题(完美篇)_晴天小哥哥的博客-CSDN博客

创建react-ts项目(简易) - 掘金 

 yarn npm 设置淘宝镜像_AlbertGou的博客-CSDN博客

 路由 | UmiJS

package-lock.json found. Your project contains lock files generated by tools,yarn和npm一起使用了解决方式_warning package-lock.json found. your project cont_KAGHQ的博客-CSDN博客

TypeScript 与 JavaScript:你应该知道的区别 - 掘金 

java后台接收json数据_json对象,后端实体类怎么接_随影随行的博客-CSDN博客 

TypeScript中文网 · TypeScript——JavaScript的超集 

如何开始使用ts,又如何将ts编译成js - 掘金 

Axios or fetch():你更中意哪一个? - 掘金 

axios基本使用及封装 - 掘金 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐