Redux之RTKQ的使用
RTKQ 是 React Toolkit Query 的简写
RTKQ可以很方便的为我们实现Ajax API的管理
安装RTKQ
RTKQ目前已经集成在RTK工具包内,我们只需要安装RTK即可
# NPM
npm install @reduxjs/toolkit
# Yarn
yarn add @reduxjs/toolkit
编写一个基本的API store
首先在src
目录内创建一个store
文件夹,在其中创建index.js
文件
import { configureStore} from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/dist/query";
import studentApi from './studentApi'
const store = configureStore({
//将api对象配置到reducer里
reducer: {
[studentApi.reducerPath]: studentApi.reducer
},
//中间件 可以扩展store (RTKQ缓存)
middleware: getDefaultMiddleware => getDefaultMiddleware().concat(studentApi.middleware)
})
setupListeners(store.dispatch)//设置以后才可以支持 refetchOnFocus refetchOnReconnect
export default store
在store
创建studentApi
文件夹,在其中创建index.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/dist/query/react";
//创建Api对象
//RTKQ的所有功能都需要该对象才能进行
const studentApi = createApi({
reducerPath: "studentApi", //api标识,不能和其他apireducer重复
//fetchBaseQuery其实就是fetch套壳
baseQuery: fetchBaseQuery({
baseUrl: "http://localhost:8888/api/",
}), //用来指定查询的基础信息,发送请求使用的工具
tagTypes: ['student'],//指定API中标签的类型
endpoints(build) {
return {
// 这些请求都带缓存
getStudents: build.query({
query() {
//指定请求的子路径
return "students";
},
//处理返回的数据
transformResponse(baseQueryReturnValue) {
return baseQueryReturnValue.data
},
providesTags: [{
type: 'student',
id: 'list'
}]
}),
getStudentById: build.query({
query(id) {
return `students/${id}`
},
transformResponse(baseQueryReturnValue) {
return baseQueryReturnValue.data
},
// keepUnusedDataFor: 0,//设置数据的缓存时间s(默认60秒)
//也可以写成回调函数的形式,三个参数,res,err和query中的参数(id)
//返回一个数组
//这样写可以细化列表请求,添加数据的时候,老数据还是可以保留缓存,不至于刷新整个列表
providesTags: (result, err, id) => {
return [{ type: 'student', id }]
}
}),
deleteStudent: build.mutation({//改动需要使用mutation
query(id) {
//发送的不是get请求,需要返回一个对象
return {
url: `students/${id}`,
method: 'delete'
}
},
invalidatesTags: [{
type: 'student',
id: 'list'
}]
}),
addStudent: build.mutation({
query(stu) {
return {
url: 'students',
method: 'post',
body: {
data: stu
}
}
},
//这个设置之后,数组中的tag只要有api中的providesTags匹配,就会使providesTags所在的api数据缓存失效,从而可以达到从新获取数据的目的
//这个非常好用!数据变动后可以自动获取数据!
invalidatesTags: [{
type: 'student',
id: 'list'
}]
}),
updateStudent: build.mutation({
query(stu) {
return {
url: `students/${stu.id}`,
method: 'put',
body: {
data: stu.attributes
}
}
},
//别忘了返回的是一个数组,是可以传多个tag的
invalidatesTags: (result, err, stu) => {
return [{ type: 'student', id: stu.id }, { type: "student", id: 'list' }]
}
})
};
}, //endpotints 需要一个对象作为返回值,指定
});
// api对象创建完毕后,对象中会根据各种方法去自动生成对应的构造函数
// 通过这些钩子函数,就可以来向服务器发送请求
//钩子函数命名规则 getStudents --> useGetStudentsQuery
export const { useGetStudentsQuery, useGetStudentByIdQuery, useDeleteStudentMutation, useAddStudentMutation, useUpdateStudentMutation } = studentApi;
export default studentApi;
在store
创建studentContext
文件夹,在其中创建index.js
import React from "react";
const studentContext = React.createContext({
getData: () => { }
})
export default studentContext
修改src/App.jsx
import "./App.css";
import StudentList from "./components/StudentList/StudentList";
import studentContext from "./store/studentContext";
import { useGetStudentsQuery } from "./store/studentApi";
function App() {
//使用自定义钩子
const { data, isSuccess, isLoading, refetch } = useGetStudentsQuery(null, {
//useQuer可以接收一个对象作为第二个参数,通过该对象可以对请求进行配置
// selectFromResult: (result) => {
// if (result.data) {
// return result.data;
// }
// },
pullingInterval: 0, //设置轮询时间间隔 单位ms 为0则不允许
skip: false, //设置是否跳过当前请求 默认false
//false表示正常缓存
refetchOnMountOrArgChange: false, //是否在挂载/参数变化时候重新加载数据 可以传时间,和bool值
//是否在重新获取焦点时重载数据(页面标签页切换)//需要store使用setupListeners(store.dispatch)
// refetchOnFocus: true,
//是否在重新连接网络时重载数据
// refetchOnReconnect: false,
});
const getDataHandler = () => {
console.log('get');
refetch();
};
return (
<studentContext.Provider
value={{
getData: getDataHandler,
}}
>
<button onClick={() => refetch()}>加载数据</button>
<div className="App">
{!isLoading && isSuccess ? (
<StudentList data={data}></StudentList>
) : (
"加载中。。"
)}
</div>
</studentContext.Provider>
);
}
export default App;
修改src/index.js
import React from 'react';
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}>
{/* //使用store */}
<App />
</Provider>
);
其中Student组件和studentform组件是为了展示列表数据的组件,这里没有进行详细展示
总之,一个简单的RTKQ API 就搭建好了