diff --git a/packages/toolkit/src/query/react/buildHooks.ts b/packages/toolkit/src/query/react/buildHooks.ts index 456275affc..cd69763b65 100644 --- a/packages/toolkit/src/query/react/buildHooks.ts +++ b/packages/toolkit/src/query/react/buildHooks.ts @@ -915,7 +915,12 @@ export function buildHooks({ (_: ApiRootState, lastResult: any) => lastResult, (_: ApiRootState) => stableArg, ], - queryStatePreSelector + queryStatePreSelector, + { + memoizeOptions: { + resultEqualityCheck: shallowEqual, + }, + } ), [select, stableArg] ) diff --git a/packages/toolkit/src/query/tests/buildHooks.test.tsx b/packages/toolkit/src/query/tests/buildHooks.test.tsx index d10d156514..e9f1f1ac90 100644 --- a/packages/toolkit/src/query/tests/buildHooks.test.tsx +++ b/packages/toolkit/src/query/tests/buildHooks.test.tsx @@ -35,7 +35,7 @@ import { server } from './mocks/server' import type { UnknownAction } from 'redux' import type { SubscriptionOptions } from '@reduxjs/toolkit/dist/query/core/apiState' import type { SerializedError } from '@reduxjs/toolkit' -import { createListenerMiddleware, configureStore } from '@reduxjs/toolkit' +import { createListenerMiddleware, configureStore, createSlice } from '@reduxjs/toolkit' import { delay } from '../../utils' import type { SubscriptionSelectors } from '../core/buildMiddleware/types' import { countObjectKeys } from '../utils/countObjectKeys' @@ -2052,7 +2052,19 @@ describe('hooks with createApi defaults set', () => { }), }) - const storeRef = setupApiStore(api) + const counterSlice = createSlice({ + name: "counter", + initialState: { count: 0 }, + reducers: { + increment(state) { + state.count++ + } + } + }) + + const storeRef = setupApiStore(api, { + counter: counterSlice.reducer, + }) expectExactType(api.useGetPostsQuery)(api.endpoints.getPosts.useQuery) expectExactType(api.useUpdatePostMutation)( @@ -2317,6 +2329,52 @@ describe('hooks with createApi defaults set', () => { await waitFor(() => expect(getRenderCount()).toBe(3)) }) + test('useQuery with selectFromResult option does not update when unrelated data in the store changes', async () => { + function Posts() { + const { posts } = api.endpoints.getPosts.useQuery(undefined, { + selectFromResult: ({ data }) => ({ + // Intentionally use an unstable reference to force a rerender + posts: data?.filter((post) => post.name.includes('post')), + }), + }) + + getRenderCount = useRenderCounter() + + return ( +
+ {posts?.map((post) => ( +
{post.name}
+ ))} +
+ ) + } + + function CounterButton() { + return ( +
storeRef.store.dispatch(counterSlice.actions.increment())} + > + Increment Count +
+ ) + } + + render( +
+ + +
, + { wrapper: storeRef.wrapper } + ) + + await waitFor(() => expect(getRenderCount()).toBe(2)) + + const incrementBtn = screen.getByTestId('incrementButton') + fireEvent.click(incrementBtn) + expect(getRenderCount()).toBe(2) + }) + test('useQuery with selectFromResult option has a type error if the result is not an object', async () => { function SelectedPost() { const _res1 = api.endpoints.getPosts.useQuery(undefined, {