Skip to content

Commit a575d4f

Browse files
committed
🐛(search) fix double request and flickering on search
The search queryKey included searchParams.toString(), creating a new React Query entry per search term (triggering fetch #1). Meanwhile, resetSearchQueryDebounced cleared the active query 500ms later (triggering fetch #2 + flicker).
1 parent 7a8cf44 commit a575d4f

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

src/frontend/src/features/providers/mailbox.tsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { useRouter } from "next/router";
66
import usePrevious from "@/hooks/use-previous";
77
import { useSearchParams } from "next/navigation";
88
import { MAILBOX_FOLDERS } from "../layouts/components/mailbox-panel/components/mailbox-list";
9-
import { useDebounceCallback } from "@/hooks/use-debounce-callback";
109

1110
type QueryState = {
1211
status: QueryStatus,
@@ -141,7 +140,7 @@ export const MailboxProvider = ({ children }: PropsWithChildren) => {
141140
const threadQueryKey = useMemo(() => {
142141
const queryKey = ['threads', selectedMailbox?.id];
143142
if (searchParams.get('search')) {
144-
return [...queryKey, 'search', searchParams.toString()];
143+
return [...queryKey, 'search'];
145144
}
146145
return [...queryKey, searchParams.toString()];
147146
}, [selectedMailbox?.id, searchParams]);
@@ -463,12 +462,6 @@ export const MailboxProvider = ({ children }: PropsWithChildren) => {
463462
await queryClient.invalidateQueries({ queryKey: ['messages', selectedThread.id] });
464463
}
465464
}
466-
const resetSearchQueryDebounced = useDebounceCallback(() => {
467-
queryClient.resetQueries(
468-
{ predicate: ({ queryKey}) => queryKey.includes('search') },
469-
);
470-
}, 500);
471-
472465
const invalidateThreadsStats = async () => {
473466
await queryClient.invalidateQueries({
474467
queryKey: ['threads', 'stats', selectedMailbox?.id],
@@ -602,9 +595,22 @@ export const MailboxProvider = ({ children }: PropsWithChildren) => {
602595
}, [selectedMailbox?.id, searchParams.toString()]);
603596

604597
useEffect(() => {
605-
if (searchParams.get('search') !== previousSearchParams?.get('search')) {
606-
resetSearchQueryDebounced();
598+
const previousSearch = previousSearchParams?.get('search');
599+
const currentSearch = searchParams.get('search');
600+
601+
if (previousSearch && !currentSearch) {
602+
// Exiting search mode: purge cached search results so re-entering
603+
// search doesn't briefly flash stale results from the previous query.
604+
queryClient.removeQueries({
605+
queryKey: ['threads', selectedMailbox?.id, 'search'],
606+
exact: true,
607+
});
608+
} else if (previousSearch && currentSearch && currentSearch !== previousSearch) {
609+
// Search term changed while already in search mode:
610+
// reset the query to force a refetch with the new params.
611+
queryClient.resetQueries({ queryKey: ['threads', selectedMailbox?.id, 'search'] });
607612
}
613+
608614
unselectThread();
609615
}, [hasSearchParamsChanged])
610616

0 commit comments

Comments
 (0)