diff --git a/packages/toolkit/src/query/react/buildHooks.ts b/packages/toolkit/src/query/react/buildHooks.ts index daec42efe2..2e595df5ec 100644 --- a/packages/toolkit/src/query/react/buildHooks.ts +++ b/packages/toolkit/src/query/react/buildHooks.ts @@ -1035,8 +1035,6 @@ export function buildHooks({ skipPollingIfUnfocused, }) - const lastRenderHadSubscription = useRef(false) - // TODO: Change this to `useRef>(undefined)` after upgrading to React 19. /** * @todo Change this to `useRef>(undefined)` after upgrading to React 19. @@ -1059,11 +1057,7 @@ export function buildHooks({ } const subscriptionRemoved = - !currentRenderHasSubscription && lastRenderHadSubscription.current - - usePossiblyImmediateEffect(() => { - lastRenderHadSubscription.current = currentRenderHasSubscription - }) + !currentRenderHasSubscription && promiseRef.current !== undefined usePossiblyImmediateEffect((): void | undefined => { if (subscriptionRemoved) { diff --git a/packages/toolkit/src/query/tests/buildHooks.test.tsx b/packages/toolkit/src/query/tests/buildHooks.test.tsx index 50ff561148..02be5d89fb 100644 --- a/packages/toolkit/src/query/tests/buildHooks.test.tsx +++ b/packages/toolkit/src/query/tests/buildHooks.test.tsx @@ -895,6 +895,71 @@ describe('hooks tests', () => { status: 'uninitialized', }) }) + +test('hook should not be stuck loading post resetApiState after re-render', async () => { + const user = userEvent.setup() + + function QueryComponent() { + const { isLoading, data } = api.endpoints.getUser.useQuery(1) + + if (isLoading) { + return

Loading...

+ } + + return

{data?.name}

+ } + + function Wrapper() { + const [open, setOpen] = useState(true) + + const handleRerender = () => { + setOpen(false) + setTimeout(() => { + setOpen(true) + }, 1000) + } + + const handleReset = () => { + storeRef.store.dispatch(api.util.resetApiState()) + } + + return ( + <> + + {open ? ( +
+ + + +
+ ) : null} + + ) + } + + render(, { wrapper: storeRef.wrapper }) + + await user.click( + screen.getByRole('button', { name: /Rerender component/i }), + ) + await waitFor(() => { + expect(screen.getByText('Timmy')).toBeTruthy() + }) + + await user.click( + screen.getByRole('button', { name: /reset api state/i }), + ) + await waitFor(() => { + expect(screen.queryByText('Loading...')).toBeNull() + }) + await waitFor(() => { + expect(screen.getByText('Timmy')).toBeTruthy() + }) + }) }) test('useQuery refetch method returns a promise that resolves with the result', async () => {