Skip to content

三、使用RTKQ请求数据

1、安装

RTKQ已经集成在了RTK中,如果我们已经在项目中引入了RTK则无需再引入其余的模块。如果你不想使用RTKQ给我们提供的发送请求的方式(简单封装过的fetch),你还需要引入一下你要使用的发送请求的工具。

2、代码演示

  • studentApi
js
//  ./store/studentApi.js
import {createApi,fetchBaseQuery} from "@reduxjs/toolkit/dist/query/react"

//创建Api对象-----createApi()用来创建RTKQ中的Api对象
const studentApi=createApi({
	reducerPath:'studentApi',//Api的标识,防止打包后调用时名词重复
    baseQuery:fetchBaseQuery({
        baseUrl:"http://localhost:1337/api/",
        prepareHeaders:(headers,{getState})=>{
            //获取用户的token
            const token=getState().auth.token
            if(token){
                 headers.set("Authorization",`Bearer ${token}`)
		    }
            return headers;
        }//用来统一设置请求头
    }),//指定查询的基本信息,发送请求使用的工具
    tagTypes:[{type:'student',id:'LIST'}],//用来指定Api中的标签类型
    endpoints(bulid){//endpoints用来指定Api中的各种功能,是一个方法,需要一个对象作为返回值
        //build是请求的构建器,通过bulid来设置请求的相关信息
        return {
            //查询方法
            getStudents:build.query({
                query(){
                    //返回请求地址的子路径
                    return 'student'
                },
                transformResponse(baseQueryReturnValue){//transformResponse用来转化响应数据的格式
                    return baseQueryReturnValue.data
                },
               providesTags: [{type: 'student', id: 'LIST'}]//标签生效,触发这个函数
            }),
            //根据id查询
             getStudentById:build.query({
                query(id) {
                    return `students/${id}`
                },
                transformResponse(baseQueryReturnValue) {
                    return baseQueryReturnValue.data
                },
                KeepUnusedDataFor:0,//设置数据缓存的时间,单位秒,默认60秒
                providesTags:(result,error,id)=>[{type:'student',id:id}]//回调函数来通过id触发标签
            }),
            //根据id删除数据
            delStudent:build.mutation({
                query(id){
                    return {//如果发送的不是get请求,需要返回一个对象来设置请求的信息
                        url:`student/${id}`,
                        method:"delete"
                    }
                },
                invalidatesTags: ((result, error, stu) =>
                    [{type: 'student', id: stu.id}, {type: 'student', id: 'LIST'}])
            }),
            addStudent:build.mutation({
                query(stu) {
                    return {
                        url:"students",
                        method:"post",
                        body:{data:stu}
                    }
                },
                invalidatesTags:[{type:'student',id:'LIST'}]
            })
        }
    })
})

//Api对象创建后,对象会根据各种方法自动的生成对应的钩子函数,通过这些钩子函数,可以向服务器发送请求
//由于这些钩子函数是build构建出来的,所以有一个很死板的命名规则
//获取查询student的方法:'use'+'GetStudents'+'Query',
//其中,use指的是钩子函数,GetStudents指的是api里定义的函数,Query指的是查询
export const {
    useGetStudentsQuery,
    useGetStudentById,
    useDelStudentMutation
}=studentApi

//默认导出
export default studentApi;
  • 仓库引用
js
//  ./store/index.js
import {configureStore} from "@reduxjs/toolkit";
import studentApi from "./studentApi"

const store=configureStore({
    reducer:{
        [studentApi.reducerPath]:studentApi.reducer
    },
    //中间件
    //studentApi里有一个中间件,需要把这个中间件加入到store的中间件里面
    //而getDefaultMiddleware()返回的是一个数组,利用concat来合并数组
    middleware:getDefaultMiddleware=>getDefaultMiddleware().concat(studentApi.middleware)
})

export default store
  • 组件使用
js
//index.js
import ReactDOM from "react-dom/client"
import App from "./App"
import {Provider} from "react-redux"
import store from "./store"

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

const App=()=>{
    const {data....}=useGetStudentsQuery()
    ......
}

3、增

js
import {useAddStudentMutation} from "../../store/studentApi" 
const [addStudentData,addResult]=useAddStudentMutation()

4、删

js
import {useDelStudentMutation} from "./store/studentApi";
const [delStudent,result]=useDelStudentMutation()

5、改

js
import {useUpdateStudentMutation} from "../../store/studentApi"
const [updateStudentData,updateResult]=useUpdateStudentMutation()

6、查

1.查询全部数据

js
import {useGetStudentsQuery} from "./store/studentApi";
const {data,isLoading,isSuccess}=useGetStudentsQuery()//data是请求结果

2.根据id查询数据

js
import {useGetStudentByIdQuery} from "../../store/studentApi"
const {isSuccess,data:inputData,isLoading}=useGetStudentByIdQuery(props.studentId)

7、参数解析

1、增

js
//useQuery()可以接受俩个参数,第二个参数可以接受一个对象,通过这个对象对请求进行配置
const result=useGetStudentsQuery(null,{
    //指定useQeury返回的结果
    selectFromResult:result=>{
        if(result.data){
            result.data=result.data.filter(item=>item.attributes.age<18)
        }
        return result
    },
    pollingInterval:0,//设置轮询的间隔,单位毫秒,如果为0则表示不轮询
    skip:false,//设置是否跳过当前请求,默认false
    refetchOnMountOrArgChange:false,//设置是否每次都重新加载数据,false正常使用缓存,true每次都重新加载数据,数字,数据换粗的时间/秒
    refetchOnFocus:true,//重回焦点
    refetchOnReconnect:false//断网连接
    //需要在./store/index.js 里设置setupListeners(store.dispacth)
})
js
currentData:undefined//当前参数的最新数据
data:undefined//最新的数据
isError:false//布尔值,是否有错误
error:Error()//对象,有错时才存在
isFetching:true//布尔值:数据是否在加载
isLoading:true//布尔值:数据是否第一次加载
isSuccess:false//布尔值,请求是否成功
isUninitialized:false//布尔值,请求是否还没有开始发送
refetch:f()//一个函数,用来重新加载数据
status:"pending"//字符串,请求的状态

8、标签总结

js
//api标签为
tagTypes:[{type:"student",id:"STUDENT"}]
//增
invalidatesTags:[{type:"student",id:"STUDENT"}]
//删
invalidatesTags:((result, error, id)=>[{type:"student",id},{type:"student",id:"STUDENT"}])
//改
invalidatesTags:((result, error, id)=>[{type:"student",id},{type:"student",id:"STUDENT"}])
//查询所有数据
 providesTags:[{type:"student",id:"STUDENT"}]
//根据id查询数据
providesTags:(result,error,id)=>[{type:"student",id}]