Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@
"36": "When using custom hooks for context, all hooks need to be provided: .\\nHook was either not provided or not a function.",
"37": "Warning: Middleware for RTK-Query API at reducerPath \"\" has not been added to the store.\n You must add the middleware for RTK-Query to function correctly!",
"38": "Cannot refetch a query that has not been started yet.",
"39": "called \\`injectEndpoints\\` to override already-existing endpointName without specifying \\`overrideExisting: true\\`"
"39": "called \\`injectEndpoints\\` to override already-existing endpointName without specifying \\`overrideExisting: true\\`",
"40": "Hooks can only be used in Client Components"
}
4 changes: 4 additions & 0 deletions packages/toolkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
},
"./query/react": {
"types": "./dist/query/react/index.d.ts",
"react-server": {
"import": "./dist/query/react.rsc/rtk-query-react.modern.mjs",
"default": "./dist/query/react.rsc/cjs/index.js"
},
"import": "./dist/query/react/rtk-query-react.modern.mjs",
"default": "./dist/query/react/cjs/index.js"
}
Expand Down
46 changes: 46 additions & 0 deletions packages/toolkit/src/query/react/index.rsc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// This must remain here so that the `mangleErrors.cjs` build script
// does not have to import this into each source file it rewrites.
import { formatProdErrorMessage } from '@reduxjs/toolkit'

import { buildCreateApi, coreModule } from '@reduxjs/toolkit/query'
import { unboundHooksModule, reactHooksModuleName } from './module'

export * from '@reduxjs/toolkit/query'
export { ApiProvider } from './ApiProvider'

const throwFn = () => {
throw new Error('Hooks can only be used in Client Components')
}

const reactHooksModule = unboundHooksModule({
hooks: {
useDispatch: throwFn,
useSelector: throwFn,
useStore: throwFn,
},
batch: throwFn,
})

const createApi = /* @__PURE__ */ buildCreateApi(
coreModule(),
reactHooksModule()
)

export type {
TypedUseMutationResult,
TypedUseQueryHookResult,
TypedUseQueryStateResult,
TypedUseQuerySubscriptionResult,
TypedLazyQueryTrigger,
TypedUseLazyQuery,
TypedUseMutation,
TypedMutationTrigger,
TypedQueryStateSelector,
TypedUseQueryState,
TypedUseQuery,
TypedUseQuerySubscription,
TypedUseLazyQuerySubscription,
TypedUseQueryStateOptions,
} from './buildHooks'
export { UNINITIALIZED_VALUE } from './constants'
export { createApi, reactHooksModule, reactHooksModuleName }
14 changes: 12 additions & 2 deletions packages/toolkit/src/query/react/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
// This must remain here so that the `mangleErrors.cjs` build script
// does not have to import this into each source file it rewrites.
import { formatProdErrorMessage } from '@reduxjs/toolkit'
import { batch, useDispatch, useSelector, useStore } from 'react-redux'

import { buildCreateApi, coreModule } from '@reduxjs/toolkit/query'
import { reactHooksModule, reactHooksModuleName } from './module'
import { unboundHooksModule, reactHooksModuleName } from './module'

export * from '@reduxjs/toolkit/query'
export { ApiProvider } from './ApiProvider'

const reactHooksModule = unboundHooksModule({
hooks: {
useDispatch,
useSelector,
useStore,
},
batch,
})

const createApi = /* @__PURE__ */ buildCreateApi(
coreModule(),
reactHooksModule(),
reactHooksModule()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
reactHooksModule()
reactHooksModule(),

)

export type {
Expand Down
204 changes: 100 additions & 104 deletions packages/toolkit/src/query/react/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ import type {
QueryDefinition,
QueryKeys,
} from '@reduxjs/toolkit/query'
import {
batch as rrBatch,
useDispatch as rrUseDispatch,
useSelector as rrUseSelector,
useStore as rrUseStore,
} from 'react-redux'

import { createSelector as _createSelector } from 'reselect'
import { isMutationDefinition, isQueryDefinition } from '../endpointDefinitions'
import { safeAssign } from '../tsHelpers'
Expand All @@ -34,7 +29,7 @@ declare module '@reduxjs/toolkit/query' {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
ReducerPath extends string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
TagTypes extends string,
TagTypes extends string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TagTypes extends string
TagTypes extends string,

> {
[reactHooksModuleName]: {
/**
Expand All @@ -50,18 +45,18 @@ declare module '@reduxjs/toolkit/query' {
>
? QueryHooks<Definitions[K]>
: Definitions[K] extends MutationDefinition<any, any, any, any, any>
? MutationHooks<Definitions[K]>
: never
? MutationHooks<Definitions[K]>
: never
}
/**
* A hook that accepts a string endpoint name, and provides a callback that when called, pre-fetches the data for that endpoint.
*/
usePrefetch<EndpointName extends QueryKeys<Definitions>>(
endpointName: EndpointName,
options?: PrefetchOptions,
options?: PrefetchOptions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
options?: PrefetchOptions
options?: PrefetchOptions,

): (
arg: QueryArgFrom<Definitions[EndpointName]>,
options?: PrefetchOptions,
options?: PrefetchOptions
) => void
} & HooksWithUniqueNames<Definitions>
}
Expand Down Expand Up @@ -136,103 +131,104 @@ export interface ReactHooksModuleOptions {
*
* @returns A module for use with `buildCreateApi`
*/
export const reactHooksModule = ({
batch = rrBatch,
hooks = {
useDispatch: rrUseDispatch,
useSelector: rrUseSelector,
useStore: rrUseStore,
},
createSelector = _createSelector,
unstable__sideEffectsInRender = false,
...rest
}: ReactHooksModuleOptions = {}): Module<ReactHooksModule> => {
if (process.env.NODE_ENV !== 'production') {
const hookNames = ['useDispatch', 'useSelector', 'useStore'] as const
let warned = false
for (const hookName of hookNames) {
// warn for old hook options
if (countObjectKeys(rest) > 0) {
if ((rest as Partial<typeof hooks>)[hookName]) {
if (!warned) {
console.warn(
'As of RTK 2.0, the hooks now need to be specified as one object, provided under a `hooks` key:' +
'\n`reactHooksModule({ hooks: { useDispatch, useSelector, useStore } })`',
)
warned = true
export const unboundHooksModule =
({
batch: defaultBatch,
hooks: defaultHooks,
}: Required<Pick<ReactHooksModuleOptions, 'batch' | 'hooks'>>) =>
({
batch = defaultBatch,
hooks = defaultHooks,
createSelector = _createSelector,
unstable__sideEffectsInRender = false,
...rest
}: ReactHooksModuleOptions = {}): Module<ReactHooksModule> => {
if (process.env.NODE_ENV !== 'production') {
const hookNames = ['useDispatch', 'useSelector', 'useStore'] as const
let warned = false
for (const hookName of hookNames) {
// warn for old hook options
if (countObjectKeys(rest) > 0) {
if ((rest as Partial<typeof hooks>)[hookName]) {
if (!warned) {
console.warn(
'As of RTK 2.0, the hooks now need to be specified as one object, provided under a `hooks` key:' +
'\n`reactHooksModule({ hooks: { useDispatch, useSelector, useStore } })`'
)
warned = true
}
}
// migrate
// @ts-ignore
hooks[hookName] = rest[hookName]
}
// then make sure we have them all
if (typeof hooks[hookName] !== 'function') {
throw new Error(
`When using custom hooks for context, all ${
hookNames.length
} hooks need to be provided: ${hookNames.join(
', '
)}.\nHook ${hookName} was either not provided or not a function.`
)
}
// migrate
// @ts-ignore
hooks[hookName] = rest[hookName]
}
// then make sure we have them all
if (typeof hooks[hookName] !== 'function') {
throw new Error(
`When using custom hooks for context, all ${
hookNames.length
} hooks need to be provided: ${hookNames.join(
', ',
)}.\nHook ${hookName} was either not provided or not a function.`,
)
}
}
}

return {
name: reactHooksModuleName,
init(api, { serializeQueryArgs }, context) {
const anyApi = api as any as Api<
any,
Record<string, any>,
any,
any,
ReactHooksModule
>
const { buildQueryHooks, buildMutationHook, usePrefetch } = buildHooks({
api,
moduleOptions: {
batch,
hooks,
unstable__sideEffectsInRender,
createSelector,
},
serializeQueryArgs,
context,
})
safeAssign(anyApi, { usePrefetch })
safeAssign(context, { batch })
return {
name: reactHooksModuleName,
init(api, { serializeQueryArgs }, context) {
const anyApi = api as any as Api<
any,
Record<string, any>,
any,
any,
ReactHooksModule
>
const { buildQueryHooks, buildMutationHook, usePrefetch } = buildHooks({
api,
moduleOptions: {
batch,
hooks,
unstable__sideEffectsInRender,
createSelector,
},
serializeQueryArgs,
context,
})
safeAssign(anyApi, { usePrefetch })
safeAssign(context, { batch })

return {
injectEndpoint(endpointName, definition) {
if (isQueryDefinition(definition)) {
const {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription,
} = buildQueryHooks(endpointName)
safeAssign(anyApi.endpoints[endpointName], {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription,
})
;(api as any)[`use${capitalize(endpointName)}Query`] = useQuery
;(api as any)[`useLazy${capitalize(endpointName)}Query`] =
useLazyQuery
} else if (isMutationDefinition(definition)) {
const useMutation = buildMutationHook(endpointName)
safeAssign(anyApi.endpoints[endpointName], {
useMutation,
})
;(api as any)[`use${capitalize(endpointName)}Mutation`] =
useMutation
}
},
}
},
return {
injectEndpoint(endpointName, definition) {
if (isQueryDefinition(definition)) {
const {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription,
} = buildQueryHooks(endpointName)
safeAssign(anyApi.endpoints[endpointName], {
useQuery,
useLazyQuery,
useLazyQuerySubscription,
useQueryState,
useQuerySubscription,
})
;(api as any)[`use${capitalize(endpointName)}Query`] = useQuery
;(api as any)[`useLazy${capitalize(endpointName)}Query`] =
useLazyQuery
} else if (isMutationDefinition(definition)) {
const useMutation = buildMutationHook(endpointName)
safeAssign(anyApi.endpoints[endpointName], {
useMutation,
})
;(api as any)[`use${capitalize(endpointName)}Mutation`] =
useMutation
}
},
}
},
}
}
}
7 changes: 7 additions & 0 deletions packages/toolkit/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ const entryPoints: EntryPointOptions[] = [
extractionConfig: 'api-extractor.query-react.json',
externals: ['redux', '@reduxjs/toolkit'],
},
{
prefix: 'rtk-query-react',
folder: 'query/react.rsc',
entryPoint: 'src/query/react/index.rsc.ts',
extractionConfig: 'api-extractor.query-react.json',
externals: ['redux', '@reduxjs/toolkit'],
},
]

function writeCommonJSEntry(folder: string, prefix: string) {
Expand Down
Loading