RTK query 9 months ago
简介
RTK Query 是 Redux Toolkit 提供的一个强大的数据获取和缓存工具。它简化了与服务器进行数据交互的过程,减少了手动管理请求状态的复杂性。以下是一些常见的使用场景:
- 数据获取和缓存:RTK Query 可以轻松地从服务器获取数据并自动缓存,以减少不必要的网络请求。
- 自动重试失败请求:RTK Query 支持自动重试失败的请求,确保数据获取的可靠性。
- 数据同步:当数据发生变化时,RTK Query 可以自动更新缓存中的数据,保持前端和后端数据的一致性。
- 简化的状态管理:RTK Query 自动处理请求的状态(如加载中、成功、失败),减少了手动管理这些状态的代码量。
- 优化的性能:通过缓存和去重请求,RTK Query 可以显著提高应用的性能。
需要注意的是RTK QUERY是可选的
RTK Query在typescript中的使用
在 TypeScript 中使用 RTK Query 需要一些额外的类型定义。以下是如何在 TypeScript 中使用 RTK Query 的基本步骤:
1,安装 Redux Toolkit 和 RTK Query:
npm install @reduxjs/toolkit react-redux
2, 创建 API Slice: 在 src/services
目录下创建一个 api.ts 文件,并定义一个 API slice。
// src/services/api.ts
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
interface Post {
id: number;
title: string;
body: string;
}
export const api = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({
query: () => 'posts',
}),
}),
});
export const { useGetPostsQuery } = api;
3, 配置 Redux Store: 在 src/app/store.ts
中配置 Redux store,并添加 API slice 的 reducer。
// src/app/store.ts
import { configureStore } from '@reduxjs/toolkit';
import { setupListeners } from '@reduxjs/toolkit/query'
import { api } from '../services/api';
export const store = configureStore({
reducer: {
[api.reducerPath]: api.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(api.middleware),
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
// optional, but required for refetchOnFocus/refetchOnReconnect behaviors
// see `setupListeners` docs - takes an optional callback as the 2nd arg for customization
setupListeners(store.dispatch)
4, 提供 Redux Store: 在 src/index.tsx
中使用 Provider 提供 Redux store。
// src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
5, 使用 API Slice: 在组件中使用 useGetPostsQuery 钩子来获取数据。
// src/components/Posts.tsx
import React from 'react';
import { useGetPostsQuery } from '../services/api';
const Posts: React.FC = () => {
const { data, error, isLoading } = useGetPostsQuery();
if (isLoading) return <>Loading...</>;
if (error) return <>Oh no, there was an error</>;
return (
<div>
<h1>Posts</h1>
<ul>
{data?.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
};
export default Posts;
或者这样表示:
import React from 'react';
import { useGetPostsQuery } from '../services/api';
const Posts: React.FC = () => {
const { data, error, isLoading } = useGetPostsQuery();
return (
<div>
{isLoading ? (
<>Loading...</>
) : error ? (
<>Oh no, there was an error</>
) : (
<>
<h1>Posts</h1>
<ul>
{data?.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</>
)}
</div>
);
};
export default Posts;
6, 在应用中使用组件: 在 src/App.tsx
中导入并使用 Posts 组件。
// src/App.tsx
import React from 'react';
import Posts from './components/Posts';
const App: React.FC = () => {
return (
<div>
<Posts />
</div>
);
};
export default App;
通过以上步骤,你就可以在 TypeScript 中使用 RTK Query 来进行数据获取和缓存。
如何添加自定义header
还是以上面的例子为例,只需要在fetchBaseQuery中添加header即可
// src/services/api.ts
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
interface Post {
id: number;
title: string;
body: string;
}
export const api = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({
baseUrl: '/api',
prepareHeaders: (headers) => {
headers.set('authorization', `Bearer YOUR_TOKEN_HERE`);
return headers;
},
}),
endpoints: (builder) => ({
getPosts: builder.query<Post[], void>({
query: () => 'posts',
}),
}),
});
export const { useGetPostsQuery } = api;
但是每个api都这么写显然有些麻烦,我们可以把baseQuery提出来:
prepareHeaders
用于在发出任何请求之前设置自定义头 X-Custom-Header
我们只将 ‘X-Custom-Header’ 和 ‘your-custom-header-value’ 替换成自己所需的header即可
import { fetchBaseQuery } from '@reduxjs/toolkit/query/react';
const baseQuery = fetchBaseQuery({
baseUrl: 'https://api.your-really-great-app.com/v1/',
prepareHeaders: (headers, { getState }) => {
// Add your custom header here
headers.set('X-Custom-Header', 'your-custom-header-value');
return headers;
},
});
export const apiSlice = createApi({
reducerPath: 'api',
baseQuery: baseQuery,
endpoints: (builder) => ({
getSomething: builder.query({
query: () => '/something',
}),
}),
});
export const { useGetSomethingQuery } = apiSlice;
- 上一篇: react loading...
- 下一篇: mui开发总结