日期:2022年10月3日

RTKQ结合Axios

上周收到同学的提问,不知道如何在RTKQ中使用Axios,这节课我们来解决一下这个问题。

先来看看一个简单的案例:

import React from "react"
import ReactDOM from "react-dom/client"
import { Provider } from "react-redux"
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/dist/query/react"
import { configureStore } from "@reduxjs/toolkit"
import { setupListeners } from "@reduxjs/toolkit/dist/query"

const productApi = createApi({
    reducerPath: "productApi",
    baseQuery: fetchBaseQuery({
        baseUrl:
            "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store",
    }),
    endpoints(build) {
        return {
            getProducts: build.query({
                query() {
                    return {
                        url: "/products.json",
                    }
                },
            }),
        }
    },
})

const { useGetProductsQuery } = productApi

const store = configureStore({
    reducer: {
        [productApi.reducerPath]: productApi.reducer,
    },

    middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware().concat(productApi.middleware),
})

setupListeners(store.dispatch)

const App = () => {
    const { data, isSuccess } = useGetProductsQuery()

    return (
        <div>
            App
            <hr />
            {isSuccess && JSON.stringify(data)}
        </div>
    )
}

const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(
    <Provider store={store}>
        <App />
    </Provider>
)

上例中productApi用来调用product数据,定义api时的baseQuery属性用来指定我们要使用的发送请求的工具,其中的fetchBaseQuery是RTKQ中为我们提供的工具,它对Fetch进行了包装,设置后RTKQ中将会使用Fetch做为发送请求的工具。

BaseQuery

要设置通过Axios发送请求,关键就在于BaseQuery。只需要使用Axios的BaseQuery替换掉fetchBaseQuery即可。但是可惜的是RTKQ中并没有为我们提供Axios的BaseQuery,所以我们需要自定义一个BaseQuery才能达到目的。

BaseQuery本身就是一个函数,定义BaseQuery直接定义一个函数即可,可以通过函数的参数来指定查询中要使用的默认参数,比如baseUrl,参数可以根据自己的实际需要指定:

const myBaseQuery = ({baseUrl} = {baseUrl:""}) => {
    
}

BaseQuery需要一个函数作为返回值,这个函数将会成为最终的发送请求的工具,且函数的返回值将会作为执行结果返回。我们可以将发送请求的逻辑编写到函数中,并且根据不同的情况设置返回值。

先看看返回值的格式,返回值的格式有两种,一种是请求成功返回的数据,一种是请求失败返回的数据:

return { data: YourData } // 请求成功返回的数据
return { error: YourError } // 请求失败返回的数据

我们先尝试定义一个简单的BaseQuery:

const myBaseQuery = () => {
  return () => {
      if(Math.random() > .5){
        return {
          data:{name:"孙悟空"}
        }
      }else{
        return {
          error:{message:"出错了"}
        }
      }
  }
}

这个BaseQuery不会真的去加载数据,而是根据随机数返回不同的数据。随机数大于0.5时会返回成功的数据,否则返回错误的数据。接下来修改Api的代码,将fetchBaseQuery修改为,myBaseQuery:

const productApi = createApi({
    reducerPath: "productApi",
    baseQuery: myBaseQuery(),
    endpoints(build) {
        return {
            getProducts: build.query({
                query() {
                    return {
                        url: "/products.json",
                    }
                },
            }),
        }
    },
})

axiosBaseQuery

如果你能理解myBaseQuery,下边我们尝试编写一个axiosBaseQuery:

const axiosBaseQuery = ({baseUrl} = {baseUrl:""}) => {
    return ({url, method, data, params}) => {
        return axios({
            url: baseUrl + url,
            method,
            data,
            params
        })
    }
}

直接使用axiosBaseQuery替换掉之前的BaseQuery,即可在RTKQ中使用Axios来发送请求了,同时我们也可以根据需要在BaseQuery中对axios做一些更详细的配置。

代码地址:

链接:https://pan.baidu.com/s/1vYLzn_p44wvZVIlZ9EqK2g?pwd=mo05
提取码:mo05

4.8 6 投票数
文章评分
订阅评论
提醒
guest

2 评论
最旧
最新 最多投票
内联反馈
查看所有评论
晴天React
晴天React
1 月 前

最近面试被问到了埋点,老师能举个案例抽空讲讲吗

2
0
希望看到您的想法,请您发表评论x