From 131ac8e341e11c597904ce3c7b1bfcee162ac31c Mon Sep 17 00:00:00 2001 From: AMin Date: Sun, 25 Oct 2026 13:30:29 +0800 Subject: [PATCH 1/2] fix(useSearchParam): refresh when the parameter name changes --- src/useSearchParam.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/useSearchParam.ts b/src/useSearchParam.ts index 64440d200e..592145ac71 100644 --- a/src/useSearchParam.ts +++ b/src/useSearchParam.ts @@ -14,6 +14,8 @@ const useSearchParam: UseQueryParam = (param) => { setValue(getValue(location.search, param)); }; + onChange(); + on(window, 'popstate', onChange); on(window, 'pushstate', onChange); on(window, 'replacestate', onChange); @@ -23,7 +25,7 @@ const useSearchParam: UseQueryParam = (param) => { off(window, 'pushstate', onChange); off(window, 'replacestate', onChange); }; - }, []); + }, [param]); return value; }; From 2feeddcc20faa659da1eadc58863a3ccc572ae8b Mon Sep 17 00:00:00 2001 From: AMin Date: Sun, 25 Oct 2026 13:31:54 +0800 Subject: [PATCH 2/2] test(useSearchParam): cover changing parameter names --- tests/useSearchParam.test.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/useSearchParam.test.ts b/tests/useSearchParam.test.ts index d3be101631..2e9a947ed2 100644 --- a/tests/useSearchParam.test.ts +++ b/tests/useSearchParam.test.ts @@ -35,6 +35,38 @@ it('returns null if search param not found', () => { expect(result.current).toBe(null); }); +it('reads the new parameter when its name changes', () => { + mockSearch = 'foo=bar&baz=quux'; + const { result, rerender } = renderHook(({ param }) => useSearchParam(param), { + initialProps: { param: 'foo' }, + }); + + rerender({ param: 'baz' }); + expect(result.current).toBe('quux'); + + rerender({ param: 'missing' }); + expect(result.current).toBe(null); +}); + +it.each(['popstate', 'pushstate', 'replacestate'])( + 'tracks the new parameter on %s after its name changes', + (event) => { + mockSearch = 'foo=bar&baz=quux'; + const { result, rerender, unmount } = renderHook(({ param }) => useSearchParam(param), { + initialProps: { param: 'foo' }, + }); + + rerender({ param: 'baz' }); + act(() => { + mockSearch = 'foo=1&baz=2'; + window.dispatchEvent(new Event(event)); + }); + + expect(result.current).toBe('2'); + unmount(); + } +); + it('tracks the latest search param value', () => { mockSearch = 'foo=bar&baz=quux';