RTKQ
createApi() 用来创建RTKQ中的API对象
RTKQ的所有功能都需要通过该对象来进行
createApi() 需要一个对象作为参数
reducerPath: Api的标识 不能和其他的Api或reducer重复
baseQuery: 指定查询的基础信息,发送请求使用的工具
endpoints: 用来指定Api中的各种功能,是一个方法,需要一个对象作为返回值
build: 是请求的构建器,通过build来设置请求的相关信息
transformResponse: 用来转换响应数据的格式
Api对象创建后,对象会根据各种方法自动的生成对应的钩子函数
通过这些钩子函数,可以来向服务器发送请求
钩子函数的命名规则 getStudents -> useGetStudentsQuery
下面是一个案例
studentApi.js
import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/dist/query/react'
const studentApi = createApi({
reducerPath: 'studentApi',
baseQuery: fetchBaseQuery({
baseUrl: 'http://,,,/api/'
}),
endpoints(build) {
return {
getStudents: build.query({
query() {
// 用来请求子路径
return 'students'
},
transformResponse(baseQueryReturnValue, meta, arg){
return baseQueryReturnValue.data
}
})
}
}
})
export const {
useGetStudentsQuery
} = studentApi
export default studentApi
index.js
import {congigureStore} from '@reduxjs/toolkit'
import studentApi from './studentApi'
const store = configureStore({
reducer:{
[studentApi.reducerPath]: studentApi.reducer
},
middleware: getDefaultMiddleware =>
getDefaultMiddleware().concat(studentApi.middleware)
})
export default store
app.js
import React from 'react';
import {useGetStudentsQuery} from "./store/studentApi";
const App = () => {
// 调用Api查询数据
// 这个钩子函数它会返回一个对象作为返回值,请求过程中相关数据都在该对象中存储
const {data, isSuccess, isLoading} = useGetStudentsQuery(); // 调用Api中的钩子查询数据
return (
<div>
{isLoading && <p>数据加载中...</p>}
{isSuccess && data.data.map(item => <p key={item.id}>
{item.attributes.name} ---
{item.attributes.age} ---
{item.attributes.gender} ---
{item.attributes.address}
</p>)}
</div>
);
};
export default App;
根据id获取student
import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/dist/query/react'
const studentApi = createApi({
reducerPath: 'studentApi',
baseQuery: fetchBaseQuery({
baseUrl: 'http://,,,/api/'
}),
endpoints(build) {
return {
getStudents: build.query({
query() {
// 用来请求子路径
return 'students'
},
transformResponse(baseQueryReturnValue, meta, arg){
return baseQueryReturnValue.data
}
}),
getStudentById:build.query({
query(id) {
return `students/${id}`
},
transformResponse(baseQueryReturnValue, meta, arg){
return baseQueryReturnValue,data
}
})
}
}
})
export const {
useGetStudentsQuery,
useGetStudentByIdQuery
} = studentApi
export default studentApi
RTKQ的缓存
keepUnusedDataFor :设置数据缓存的时间 单位秒 默认60s
import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/dist/query/react'
const studentApi = createApi({
reducerPath: 'studentApi',
baseQuery: fetchBaseQuery({
baseUrl: 'http://,,,/api/'
}),
endpoints(build) {
return {
getStudents: build.query({
query() {
// 用来请求子路径
return 'students'
},
transformResponse(baseQueryReturnValue, meta, arg){
return baseQueryReturnValue.data
}
}),
getStudentById:build.query({
query(id) {
return `students/${id}`
},
transformResponse(baseQueryReturnValue, meta, arg){
return baseQueryReturnValue,data
},
keepUnuseDataFor:60,
})
}
}
})
export const {
useGetStudentsQuery,
useGetStudentByIdQuery
} = studentApi
export default studentApi
useQuery的返回值
currentData: undefined 当前参数的最新数据
data: undefined 最新数据
isError: false 布尔值 是否有错误
error: Error() 对象 有错误时才存在
isFetrching: true 布尔值 数据是否在加载
isLoading: true 布尔值 数是否第一次加载
isSuccess: false 布尔值 请求是否成功
isUninitialized: false 布尔值 请求是否还没有开始发送
refetch: f() 一个函数 用来重新加载数据
status: ”pending“ 字符串 请求的状态
import React from 'react';
import {useGetStudentsQuery} from "./store/studentApi";
import StudentList from "./components/StudentList";
let num = 0;
const App = () => {
const result = useGetStudentsQuery(num);
console.log(result.data, result.currentData);
const {data:stus, isSuccess, isLoading, refetch} = result; // 调用Api中的钩子查询数据
return (
<div>
<button onClick={()=>refetch()}>刷新</button>
<button onClick={()=>num++}>改变num</button>
{isLoading && <p>数据加载中...</p>}
{isSuccess && <StudentList stus={stus}/>}
</div>
);
};
export default App;
useQuery的参数
useQuery可以接收一个对象作为第二个参数 通过该对象可以对请求进行配置
selectFromResult 用来执行useQuery返回的结果
pollingInterval 设置轮询的间隔 单位毫秒 如果为0则表示不轮询
skip 设置是否跳过当前请求 默认false
refetchOnMountOrArgChange 设置是否每次都重新加载数据 false正常使用缓存 true每次都重载数据 数字 数据缓存的时间(秒)
refetchOnFocus 是否在重新获取焦点时重载数据
refetchOnReconnect 是否在重新连接后重载数据
import React from 'react';
import {useGetStudentsQuery} from "./store/studentApi";
import StudentList from "./components/StudentList";
const App = () => {
const result = useGetStudentsQuery(null, {
selectFromResult: result => {
if (result.data) {
result.data = result.data.filter(item => item.attributes.age < 18);
}
return result;
},
pollingInterval:0,
skip:false,
refetchOnMountOrArgChange:false,
refetchOnFocus:false,
refetchOnReconnect:true,
});
const {data: stus, isSuccess, isLoading, refetch} = result; // 调用Api中的钩子查询数据
return (
<div>
<button onClick={() => refetch()}>刷新</button>
{isLoading && <p>数据加载中...</p>}
{isSuccess && <StudentList stus={stus}/>}
</div>
);
};
export default App;
import {configureStore} from "@reduxjs/toolkit";
import studentApi from "./studentApi";
import {setupListeners} from "@reduxjs/toolkit/query";
const store = configureStore({
reducer:{
[studentApi.reducerPath]:studentApi.reducer
},
middleware:getDefaultMiddleware =>
getDefaultMiddleware().concat(studentApi.middleware)
});
setupListeners(store.dispatch); // 设置以后,将会支持 refetchOnFocus refetchOnReconnect
export default store;
RTKQ删除数据
import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/dist/query/react'
const studentApi = createApi({
reducerPath: 'studentApi',
baseQuery: fetchBaseQuery({
baseUrl: 'http://,,,/api/'
}),
endpoints(build) {
return {
getStudents: build.query({
query() {
// 用来请求子路径
return 'students'
},
transformResponse(baseQueryReturnValue, meta, arg){
return baseQueryReturnValue.data
}
}),
getStudentById:build.query({
query(id) {
return `students/${id}`
},
transformResponse(baseQueryReturnValue, meta, arg){
return baseQueryReturnValue,data
},
keepUnuseDataFor:60,
}),
delStudent: build.mutation({
return {
// 如果发送的get请求,需要返回一个对象来设置请求的信息
url: `students/${id}`,
method: 'delete'
}
})
}
}
})
export const {
useGetStudentsQuery,
useGetStudentByIdQuery,
useDelStudentMutation,
} = studentApi
export default studentApi
RTKQ添加与修改
import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/dist/query/react'
const studentApi = createApi({
reducerPath: 'studentApi',
baseQuery: fetchBaseQuery({
baseUrl: 'http://,,,/api/'
}),
endpoints(build) {
return {
getStudents: build.query({
query() {
// 用来请求子路径
return 'students'
},
transformResponse(baseQueryReturnValue, meta, arg){
return baseQueryReturnValue.data
}
}),
getStudentById:build.query({
query(id) {
return `students/${id}`
},
transformResponse(baseQueryReturnValue, meta, arg){
return baseQueryReturnValue,data
},
keepUnuseDataFor:60,
}),
delStudent: build.mutation({
return {
// 如果发送的get请求,需要返回一个对象来设置请求的信息
url: `students/${id}`,
method: 'delete'
}
}),
addStudent: build.mutation({
query(stu) {
return {
url: 'students',
method: 'post',
body: {data: stu}
}
}
}),
updateStudent: build.mutation({
query(stu) {
return {
url: `students/${stu.id}`,
method: 'put',
body: {data: stu.attributes}
}
}
})
}
}
})
export const {
useGetStudentsQuery,
useGetStudentByIdQuery,
useDelStudentMutation,
useAddStudentMutation,
useUpdateStudentMutation
} = studentApi
export default studentApi
对于删除 增加 修改
调用钩子函数后 返回的是一个数组 数组中有两个东西 第一个是操作的触发器 第二个是结构集
const [delStudent, {isSuccess}] = useDelStudentMutation();
const [addStudent, {isSuccess:isAddSuccess}] = useAddStudentMutation();
const [updateStudent, {isSuccess:isUpdateSuccess}] = useUpdateStudentMutation();
RTKQ中,给Api切片请求的数据打上标签
给Api切片的配置对象添加 tagTypes属性,该属性的属性值是个数组。数组内存入需要用到的标签
tagTypes: ['student'], // 用来指定Api中的标签类型
给Api切片的钩子函数添加 providesTags属性,属性值为标签数组。数组添加标签后,该钩子函数请求的数据就打上了标签
getStudents: build.query({
query() {
return 'students';
},
transformResponse(baseQueryReturnValue, meta, arg) {
return baseQueryReturnValue.data;
},
providesTags: [{type: 'student', id: 'LIST'}]
}),
当providesTags属性的值为回调函数时,可以对标签的生效范围做更细致的划分
参数1:网络请求的返回结果
参数2:错误信息
参数3:钩子函数中传入的实参
//返回值为一个数组,符合数组元素条件的数据将生效。
getStudentById: build.query({
query(id) {
return `students/${id}`;
},
transformResponse(baseQueryReturnValue, meta, arg) {
return baseQueryReturnValue.data;
},
keepUnusedDataFor: 60,
providesTags: (result, error, id) => [{type: 'student', id}]
}),
给Api切片的钩子函数添加 invalidatesTags属性,属性值为标签输入。数组内存入标签后,对应的标签失效。标签失效后,网络请求的数据重新加载。
- 注意:代码 invalidatesTags:[‘student’] ,是使得该标签的所有数据都失效
updateStudent: build.mutation({
query(stu) {
return {
url: `students/${stu.id}`,
method: 'put',
body: {data: stu.attributes}
};
},
invalidatesTags: ['student']
}),
同样,invalidatesTags的属性值也可以是一个回调函数,该回调函数的结构与proviedsTags的回调函数结构一致
updateStudent: build.mutation({
query(stu) {
return {
url: `students/${stu.id}`,
method: 'put',
body: {data: stu.attributes}
};
},
invalidatesTags: ((result, error, stu) =>
[{type: 'student', id: stu.id}, {type: 'student', id: 'LIST'}])
}),
};
当不需要流动的参数时,invalidatesTags的属性值可直接写成对象的数组:
addStudent: build.mutation({
query(stu) {
return {
url: 'students',
method: 'post',
body: {data: stu}
};
},
invalidatesTags: [{type: 'student', id: 'LIST'}]
}),
完整代码
import {createApi, fetchBaseQuery} from "@reduxjs/toolkit/dist/query/react";
const studentApi = createApi({
reducerPath: 'studentApi',
baseQuery: fetchBaseQuery({
baseUrl: "http://localhost:1337/api/"
}),
tagTypes: ['student'],
endpoints(build) {
return {
getStudents: build.query({
query() {
return 'students';
},
transformResponse(baseQueryReturnValue, meta, arg) {
return baseQueryReturnValue.data;
},
providesTags: [{type: 'student', id: 'LIST'}]
}),
getStudentById: build.query({
query(id) {
return `students/${id}`;
},
transformResponse(baseQueryReturnValue, meta, arg) {
return baseQueryReturnValue.data;
},
keepUnusedDataFor: 60,
providesTags: (result, error, id) => [{type: 'student', id}]
}),
delStudent: build.mutation({
query(id) {
return {
url: `students/${id}`,
method: 'delete'
};
}
}),
addStudent: build.mutation({
query(stu) {
return {
url: 'students',
method: 'post',
body: {data: stu}
};
},
invalidatesTags: [{type: 'student', id: 'LIST'}]
}),
updateStudent: build.mutation({
query(stu) {
return {
url: `students/${stu.id}`,
method: 'put',
body: {data: stu.attributes}
};
},
invalidatesTags: ((result, error, stu) =>
[{type: 'student', id: stu.id}, {type: 'student', id: 'LIST'}])
}),
};
}
});
export const {
useGetStudentsQuery,
useGetStudentByIdQuery,
useDelStudentMutation,
useAddStudentMutation,
useUpdateStudentMutation
} = studentApi;
export default studentApi;