From 49aa1a79e713d96eb6170af8727a89b25d068093 Mon Sep 17 00:00:00 2001 From: anyulled <100741+anyulled@users.noreply.github.com> Date: Mon, 6 Apr 2026 08:26:33 +0000 Subject: [PATCH] fix: correctly debounce TalksFilterBar input Fixes a bug where the search input in TalksFilterBar was not being debounced at all. The `return () => clearTimeout(...)` inside the event handler is ignored by React. By utilizing a `useRef` to store the timeout ID, we can properly clear the pending timeout across renders. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- components/layout/TalksFilterBar.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/components/layout/TalksFilterBar.tsx b/components/layout/TalksFilterBar.tsx index c05acb1f..467f096b 100644 --- a/components/layout/TalksFilterBar.tsx +++ b/components/layout/TalksFilterBar.tsx @@ -1,7 +1,7 @@ "use client"; import { usePathname, useRouter, useSearchParams } from "next/navigation"; -import { useCallback, useEffect, useState, useTransition } from "react"; +import { useCallback, useEffect, useState, useTransition, useRef } from "react"; import { motion } from "framer-motion"; interface TalksFilterBarProps { @@ -22,6 +22,8 @@ export default function TalksFilterBar({ tracks, year: _year }: TalksFilterBarPr const [selectedTrack, setSelectedTrack] = useState(searchParams.get("track") || ""); const [searchQuery, setSearchQuery] = useState(searchParams.get("q") || ""); + const timeoutRef = useRef | null>(null); + // Update state when URL changes useEffect(() => { setSelectedTrack(searchParams.get("track") || ""); @@ -60,11 +62,15 @@ export default function TalksFilterBar({ tracks, year: _year }: TalksFilterBarPr const handleSearchChange = (e: React.ChangeEvent) => { const newQuery = e.target.value; setSearchQuery(newQuery); + + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + // Debounce the URL update for search - const timeoutId = setTimeout(() => { + timeoutRef.current = setTimeout(() => { updateFilters(selectedTrack, newQuery); }, 300); - return () => clearTimeout(timeoutId); }; return (