自定义 createApi
目前,RTK Query包含两种变体的 createApi
:
createBaseApi
,只包含与UI无关的Redux逻辑(核心模块)createApi
,包含核心和React钩子模块
你可以通过为模块指定非默认选项或添加自己的模块来创建自己的 createApi
版本。
自定义 React-Redux 钩子
如果你希望钩子使用不同版本的 useSelector
,useDispatch
和 useStore
,例如,如果你正在使用自定义上下文,你可以在模块创建时传入这些:
import * as React from 'react'
import {
createDispatchHook,
createSelectorHook,
createStoreHook,
ReactReduxContextValue,
} from 'react-redux'
import {
buildCreateApi,
coreModule,
reactHooksModule,
} from '@reduxjs/toolkit/query/react'
const MyContext = React.createContext<ReactReduxContextValue>(null as any)
const customCreateApi = buildCreateApi(
coreModule(),
reactHooksModule({
hooks: {
useDispatch: createDispatchHook(MyContext),
useSelector: createSelectorHook(MyContext),
useStore: createStoreHook(MyContext),
},
}),
)
自定义 RTKQ 的 createSelector
coreModule
和 reactHooksModule
都接受一个 createSelector
选项,它应该是来自 Reselect 的选择器创建器实例,或者具有等效签名。
import * as React from 'react'
import { createSelectorCreator, lruMemoize } from '@reduxjs/toolkit'
import {
buildCreateApi,
coreModule,
reactHooksModule,
} from '@reduxjs/toolkit/query/react'
const createLruSelector = createSelectorCreator(lruMemoize)
const customCreateApi = buildCreateApi(
coreModule({ createSelector: createLruSelector }),
reactHooksModule({ createSelector: createLruSelector }),
)
创建你自己的模块
如果你想创建自己的模块,你应该查看react-hooks模块以了解实现可能是什么样子。
这是一个非常精简的版本:
import { CoreModule } from '@internal/core/module'
import {
BaseQueryFn,
EndpointDefinitions,
Api,
Module,
buildCreateApi,
coreModule,
} from '@reduxjs/toolkit/query'
export const customModuleName = Symbol()
export type CustomModule = typeof customModuleName
declare module '../apiTypes' {
export interface ApiModules<
BaseQuery extends BaseQueryFn,
Definitions extends EndpointDefinitions,
ReducerPath extends string,
TagTypes extends string,
> {
[customModuleName]: {
endpoints: {
[K in keyof Definitions]: {
myEndpointProperty: string
}
}
}
}
}
export const myModule = (): Module<CustomModule> => ({
name: customModuleName,
init(api, options, context) {
// 如果需要,可以在这里初始化一些东西
return {
injectEndpoint(endpoint, definition) {
const anyApi = api as any as Api<
any,
Record<string, any>,
string,
string,
CustomModule | CoreModule
>
anyApi.endpoints[endpoint].myEndpointProperty = 'test'
},
}
},
})
export const myCreateApi = buildCreateApi(coreModule(), myModule())