上周收到同学的提问,不知道如何在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
最近面试被问到了埋点,老师能举个案例抽空讲讲吗
安排
超哥可以安排一下前端面试题目吗,react,vue都学了,自己也写了项目,项目里router,rtk,rtkq都有用到,就是有点害怕面试