Skip to content

Commit

Permalink
Merge pull request #4177 from juliengbt/feature/4149-is-prefetch-query
Browse files Browse the repository at this point in the history
feat: add isPrefetch property in query action
  • Loading branch information
EskiMojo14 authored Feb 11, 2024
2 parents fd24f6f + 6ef71d0 commit 80b7656
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 8 deletions.
4 changes: 3 additions & 1 deletion packages/toolkit/src/query/core/buildInitiate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ You must add the middleware for RTK-Query to function correctly!`,
forceRefetch,
subscriptionOptions,
[forceQueryFnSymbol]: forceQueryFn,
} = {},
...rest
} = {}
) =>
(dispatch, getState) => {
const queryCacheKey = serializeQueryArgs({
Expand All @@ -311,6 +312,7 @@ You must add the middleware for RTK-Query to function correctly!`,
})

const thunk = queryThunk({
...rest,
type: 'query',
subscribe,
forceRefetch: forceRefetch,
Expand Down
11 changes: 6 additions & 5 deletions packages/toolkit/src/query/core/buildThunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,11 +609,12 @@ In the case of an unhandled error, no tags will be "provided" or "invalidated".`
const force = hasTheForce(options) && options.force
const maxAge = hasMaxAge(options) && options.ifOlderThan

const queryAction = (force: boolean = true) =>
(api.endpoints[endpointName] as ApiEndpointQuery<any, any>).initiate(
arg,
{ forceRefetch: force },
)
const queryAction = (force: boolean = true) => {
const options = { forceRefetch: force, isPrefetch: true }
return (
api.endpoints[endpointName] as ApiEndpointQuery<any, any>
).initiate(arg, options)
}
const latestStateValue = (
api.endpoints[endpointName] as ApiEndpointQuery<any, any>
).select(arg)(getState())
Expand Down
53 changes: 51 additions & 2 deletions packages/toolkit/src/query/tests/buildThunks.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { configureStore } from '@reduxjs/toolkit'
import { configureStore, isAllOf } from '@reduxjs/toolkit'
import { createApi } from '@reduxjs/toolkit/query/react'
import { renderHook, waitFor } from '@testing-library/react'
import { withProvider } from '../../tests/utils/helpers'
import { actionsReducer, withProvider } from '../../tests/utils/helpers'
import type { BaseQueryApi } from '../baseQueryTypes'

test('handles a non-async baseQuery without error', async () => {
Expand Down Expand Up @@ -200,3 +200,52 @@ describe('re-triggering behavior on arg change', () => {
}
})
})

describe('prefetch', () => {
const baseQuery = () => ({ data: null })
const api = createApi({
baseQuery,
endpoints: (build) => ({
getUser: build.query<any, any>({
query: (obj) => obj,
}),
}),
})

const store = configureStore({
reducer: { [api.reducerPath]: api.reducer, ...actionsReducer },
middleware: (gDM) => gDM().concat(api.middleware),
})
it('should attach isPrefetch if prefetching', async () => {
store.dispatch(api.util.prefetch('getUser', 1, {}))

await Promise.all(store.dispatch(api.util.getRunningQueriesThunk()))

const isPrefetch = (
action: any,
): action is { meta: { arg: { isPrefetch: true } } } =>
action?.meta?.arg?.isPrefetch

expect(store.getState().actions).toMatchSequence(
api.internalActions.middlewareRegistered.match,
isAllOf(api.endpoints.getUser.matchPending, isPrefetch),
isAllOf(api.endpoints.getUser.matchFulfilled, isPrefetch),
)

// compare against a regular initiate call
await store.dispatch(
api.endpoints.getUser.initiate(1, { forceRefetch: true }),
)

const isNotPrefetch = (action: any): action is unknown =>
!isPrefetch(action)

expect(store.getState().actions).toMatchSequence(
api.internalActions.middlewareRegistered.match,
isAllOf(api.endpoints.getUser.matchPending, isPrefetch),
isAllOf(api.endpoints.getUser.matchFulfilled, isPrefetch),
isAllOf(api.endpoints.getUser.matchPending, isNotPrefetch),
isAllOf(api.endpoints.getUser.matchFulfilled, isNotPrefetch),
)
})
})

0 comments on commit 80b7656

Please sign in to comment.