likes
comments
collection
share

如何在React项目中封装Axios

作者站长头像
站长
· 阅读数 22

如何在React项目中封装Axios

前言

        之前我一直使用Vue作为开发框架,然而公司后来接了一个新项目要求使用React。我只能现学现卖,从Vue向React转型。虽然最后顺利地完成了开发任务,但是在这期间固有的Vue开发思维使自己遇到了一些困难,其中就包括Axios地封装问题。下面我先会提出Vue封装方式在React项目中不适用的地方并提出自己的改进方法

Vue项目中的封装方式

        Vue项目中封装Axios一般是按照Axios官网的方式:

import axios from "axios"
const instance = axios.create({
    baseURL: baseURL,
    timeout: 1000
    //其他配置...
});

// 添加请求拦截器
instance s.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// instance 截器
axios.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
}, function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
});

        React与Vue最大的不同点就是React特有的Hook函数,包括React相关的路由、状态管理库都是使用Hook函数的思想,而Hook函数只能在React函数组件或者自定义Hook函数中使用。在上面的封装方法中如果要进行类似响应后的路由跳转或者请求前的token读取等需要使用Hook函数的操作就会因为Hook函数的特性而无法直接实现,因此我们需要将Axios封装成自定义Hook的方式。下面我们看一下具体的实现方法!

自定义Hook函数封装Axios

//useAxiosIns.js
import axios from "axios";
class Request {
    instance;
    interceptors;
    loading;
    constructor(config,interceptors) {
        //在这里可以填写一些默认的公共配置
        this.instance = axios.create(config);
        this.setGlobalInterceptor(this.instance,interceptors);
    }
    setGlobalInterceptor(instance,interceptors) {
        //请求成功拦截器
        let requestInterceptor=interceptors?.requestInterceptor||((config) => {
            return config;
        })
        //请求失败拦截器
        let requestInterceptorCatch=interceptors?.requestInterceptorCatch||((error) => {
            return Promise.reject(error);

        })
        //响应成功拦截器
        let responseInterceptor=interceptors?.responseInterceptor||(async (response) => {

            return response.data;
        })
        //相应失败拦截器
        let responseInterceptorCatch=interceptors?.responseInterceptorCatch||(async (error) => {
            return Promise.reject(error);
        })
        instance.interceptors.request.use(requestInterceptor, requestInterceptorCatch);
        instance.interceptors.response.use(responseInterceptor, responseInterceptorCatch);
    }
}
export default function useAxiosIns(config){
    return new Request(config)
}


        在上面的封装方式中我们可以在useAxiosIns中使用Hook函数,并将Hook函数返回的变量或方法通过参数传递到Axios中,这样就可以在拦截器中进行一些需要Hook函数的操作了。

        需要注意的是这样封装以后后续的请求相关的函数都需要使用自定义Hook函数的形式,下面我们看一下具体的代码(下面的代码省略了文件导入的过程):

//request.js
export default function useRequest (config={}){
    const requestIns=useAxiosIns({
        baseURL: "https://jsonplaceholder.typicode.com",
        timeout: 5000,
        ...config
        // 针对该服务的其他一些配置,如对应的拦截器与响应器
    })
    const get=(url,params,config)=>{
        return requestIns.instance.get(url, {params,...config})
    }
    const post=(url,data,config)=>{
        return requestIns.instance.post(url,data,config)
    }
    return {
        get,post
    }
}
//xxxApi.js

function usePostApi(){
    const {get,post}=useRequest();
    const getXXXApi=(params)=>{
        return get("/posts",params)
    }
    const addXXXApi=(params)=>{
        return post("/posts",params)
    }
    return {
        getPostListApi,
        addPostApi
    }
}
export default usePostApi;

结语

        以上只是对Axios进行了简单的封装,适用于一些不太复杂的项目。现在社区已经有一些现成的第三方库,如use-axios-clientuseSwr等等用于在React项目中进行数据请求,在大型项目中建议使用现成的第三方库。