redux tookit - rtk query的简单使用
redux tookit - rtk query
官网:https://redux-toolkit.js.org/rtk-query/overview
rtk query
是@reduxjs/toolkit
包中的的一个可选插件,其体系结构在内部使用redux。rtk query
是一个强大的数据获取和缓存工具,RTK Query 是一个强大的数据获取和缓存工具。它旨在简化在 Web 应用程序中加载数据的常见情况,无需自己手动编写数据获取和缓存逻辑。极大简化代码。
RTK Query 包含以下API:
- createApi
RTK query功能的核心。允许定义一组endpoints来描述如何从一系列endpoints检索数据,包括如何获取和转换该数据的配置。经验法则:每个基本URL使用一个API slice。
- fetchbasQuery
fetch 的一个小包装,旨在简化请求。
-
可以作为 Provider 使用如果你还没有redux store
- setupListeners
用于启用 refetchOnMount 和 refetchOnReconconnect 行为的实用程序
接下来我将介绍一下该工具的简单使用
引用 (可通过以下两种方式获得)
tsimport { createApi } from '@reduxjs/toolkit/query' /* React-specific entry point that automatically generates hooks corresponding to the defined endpoints */ import { createApi } from '@reduxjs/toolkit/query/react'
定义API slice
tsimport { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import type { Pokemon } from './types' // Define a service using a base URL and expected endpoints export const pokemonApi = createApi({ // 作为唯一key挂载到store reducerPath: 'rootApi', // 所有请求都以 https://fakeApi 这个开头 baseQuery: fetchBaseQuery({ baseUrl: 'https://fakeApi' }), // 代表对该服务器的操作和请求 endpoints: (builder) => ({ // builder.query<resType, reqParamType>, build.query 一般用于 GET 请求 // builder.mutation一般用于会改变数据库数据请求 比如POST请求 getPokemonByName: builder.query<Pokemon, string>({ query: (name) => `pokemon/${name}`, }), updatePokemon: builder.mutation<void, Pokemon>({ query: ({id, ...pathch}) => { url: `pokemon/${name}`, method: 'POST', body: patch }, }), }), }) // 为 `getPokemonByName` Query endpoint 导出自动生成的 hooks export const { useGetPokemonByNameQuery, useUpdatePokemonMutation } = pokemonApi
我一般会拆分开来使用,因为项目中接口请求不止一个,可以把定义API slice 放在一个文件,请求可以通过 injectEndpoints
把需要的请求放入。
roote-api.ts
tsimport {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react'; // Define a service using a base URL and expected endpoints const rootApi = createApi({ // 作为唯一key挂载到store reducerPath: 'rootApi', // 所有请求都以 https://fakeApi 这个开头 baseQuery: fetchBaseQuery({ baseUrl: 'https://fakeApi' }), // 代表对该服务器的操作和请求 endpoints: () => ({}), }); export default rootApi;
features/api/pokemon-api.js
tsimport rootApi from '@/store/root-api'; const pokemonApi = rootApi.injectEndpoints({ endpoints: builder => ({ // builder.query<resType, reqParamType>, build.query 一般用于 GET 请求 // builder.mutation一般用于会改变数据库数据请求 比如POST请求 getPokemonByName: builder.query<Pokemon, string>({ query: (name) => `pokemon/${name}`, }), updatePokemon: builder.mutation<void, Pokemon>({ query: ({id, ...pathch}) => { url: `pokemon/${name}`, method: 'POST', body: patch }, }), }), }); export const { useGetPokemonByNameQuery, useUpdatePokemonMutation } = pokemonApi
配置store
API slice 还包含一个自动生成的Redux slice reducer (rootApi.reducer) 和一个自定义中间件(rootApi.middleware),这里的rootApi是我上面定义的 API slice
store.js
tsimport postsReducer from '../features/posts/postsSlice' import usersReducer from '../features/users/usersSlice' import notificationsReducer from '../features/notifications/notificationsSlice' import { apiSlice } from '../features/api/apiSlice' export default configureStore({ reducer: { posts: postsReducer, users: usersReducer, notifications: notificationsReducer, [routApiSlice.reducerPath]: rootApi.reducer }, middleware: getDefaultMiddleware => getDefaultMiddleware().concat(rootApi.middleware) })
在组件中使用hooks
每个生成的query hooks 都会返回一个包含多个字段的对象,包括:
- data: 来自服务器的实际响应内容,收到响应之前,该字段将是
undefined
- isLoading: boolean类型, 代笔此hooks当前是否正在向服务器发出第一次请求。(注意:如果参数更改以请求不同的数据,isLoading将保持为false)
- isFetching: boolean类型,此hooks当前是否正在向服务器发出任何请求。
- isSuccess: boolean类型, 此hooks 是否已成功请求并有可用的缓存数据
- isError: boolean类型, 指最后一个请求是否有错误
- error: 一个 serialized 错误对象
tsximport * as React from 'react' import { useGetPokemonByNameQuery, useUpdatePokemonMutation } from './features/api/pokemon-api' export default function App() { // Using a query hook automatically fetches data and returns query values const { data, error, isLoading } = useGetPokemonByNameQuery('bulbasaur') // Individual hooks are also accessible under the generated endpoints: // const { data, error, isLoading } = pokemonApi.endpoints.getPokemonByName.useQuery('bulbasaur') const [trigger, { data, error, isLoading }] = useUpdatePokemonMutation() const updatePokenmon = (data) => { trigger(data); } // render UI based on data and loading state }