RTK Query:查询与添加数据
RTK Query
概述
RTK Query 是一个强大的数据获取和缓存工具。它旨在简化在 Web 应用程序中加载数据的常见情况,无需自己手动编写数据获取和缓存逻辑。
环境搭建
RTK Query 是一个包含在 Redux Toolkit 包中的可选插件,其功能构建在 Redux Toolkit 中的其他 API 之上。
添加 Redux Toolkit 和 React-Redux 依赖包到你的项目中:
npm install @reduxjs/toolkit react-redux
基本使用
本案例使用的环境是:
"react": "^18.2.0",
"@reduxjs/toolkit": "^1.9.0",
数据结构
由于我们使用的TypeScript编写,所以我们先提前定义好数据结构
// dataType/IPostState.tsx
interface IPostState {
id: string;
title: string;
content: string;
user: string;
date: string;
}
export default IPostState;
定义 API Slice
/// redux/apiSlice.tsx
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import IPostState from '../dataType/IPostState'
export const apiSlice = createApi({
reducerPath: 'baseapi',
// 服务器地址
baseQuery: fetchBaseQuery({ baseUrl: 'http://127.0.0.1:8780/fakeApi' }),
endpoints: builder => ({
//查询所有数据
// getPosts这个名字是自己起的,叫啥都行
// < >里面的泛型,第一个是请求返回数据的类型,第二个接收参数的数据类型
getPosts: builder.query<IPostState[], void>({
query: () => '/posts',
}),
// 根据id去查询特定的数据
getPostById: builder.query<IPostState, string>({
query: postId => `/postsbyid?id=${postId}`,
}),
//添加新数据
addNewPost: builder.mutation<IPostState[], IPostState>({
query: newData => ({
url: '/addposts',
method: 'POST',
body: newData
}),
}),
})
})
// 导出的方法必须是 use...Query 或 use...Mutation
// ... 为上面自定义的名字
export const {
useGetPostsQuery,
useGetPostByIdQuery,
useAddNewPostMutation
} = apiSlice
配置 Store
// redux/store.tsx
import { configureStore } from '@reduxjs/toolkit'
import { apiSlice } from './apiSlice'
const store = configureStore({
reducer: {
[apiSlice.reducerPath]: apiSlice.reducer
},
middleware: getDefaultMiddleware => getDefaultMiddleware().concat(apiSlice.middleware)
})
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
在src/index.ts中配置store仓库
// index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import store from './redux/store';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<Provider store={store}>
<App />
</Provider>
);
在组件中使用
我们就在 App.tsx 文件做一下简单的调用示例:
// App.tsx
import React from 'react'
import IPostState from './dataType/IPostState'
import { useAddNewPostMutation, useGetPostByIdQuery, useGetPostsQuery } from './redux/apiSlice'
function App() {
// isLoading 标志,如果这是第一个数据请求,则为 true,
// isFetching 标志,当任意数据请求正在进行时为true ,请求完成为flase
// isSuccess 标志, 是否已成功请求并有可用的缓存数据,请求成功为true
// isError 标识,指示请求是否有错误
// error: 一个 serialized 错误对象
//获取所有数据
const {
data: data1,
isLoading: isLoading2,
isFetching,
isSuccess,
isError,
error,
} = useGetPostsQuery()
console.log(data1)
// 获取id为'2'的数据
const { data: data2 } = useGetPostByIdQuery('2')
console.log(data2)
// 第一个值是触发函数。当被调用时,它会使用你提供的参数向服务器发出请求。这实际上就像一个已经被包装以立即调度自身的 thunk。
// 第二个值是一个对象,其中包含有关当前正在进行的请求(如果有)的元数据。这包括一个 isLoading 标志以指示请求是否正在进行中
const [addNewPost, { isLoading }] = useAddNewPostMutation()
//这里定义一个点击事件,假如我们点击一个按钮,就向服务器添加一条特殊的数据
const uploadData = () => {
//为了方便,我们自定义一个要插入的数据
let newData: IPostState = {
id: '11',
title: 'title1',
content: 'content1',
user: '2',
date: '2022-11-15T11:55:02.984Z'
}
// 添加数据
addNewPost(newData)
}
return (
<div>
<button onClick={uploadData}>添加数据</button>
</div>
)
}
export default App